Summary Statistics
PlotNParticles <- uds %>%
ggplot(aes(x = tot_nparticles, y = depth, col = profile)) +
facet_wrap(~project) +
geom_point(alpha = 0.3, shape = 1) +
scale_y_reverse() + scale_x_log10()
PlotNParticles

bdsAddTime <- bds %>%
mutate(Hour = hour(time), Day = day(time))
FSG1 <- gam(tot_nparticles~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
FSG2 <- gam(tot_nparticles ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
FSG3 <- gam(tot_nparticles ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
#FSG4 <- gam(tot_nparticles~ s(depth, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
summary(FSG1)
Family: gaussian
Link function: identity
Formula:
tot_nparticles ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4,
bs = "cc")
Parametric coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 9.002 0.106 84.96 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Approximate significance of smooth terms:
edf Ref.df F p-value
s(depth) 1.204 1.366 3.346 0.0874 .
s(Day) 1.512 1.761 3.001 0.0386 *
s(Hour) 1.579 2.000 2.713 0.0389 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
R-sq.(adj) = 0.183 Deviance explained = 24.2%
GCV = 0.73885 Scale est. = 0.67365 n = 60
#summary(FSG2)
#summary(FSG3)
#summary(FSG4)
summary(FSG1)$r.sq - summary(FSG2)$r.sq
[1] 0.07590024
summary(FSG2)$r.sq - summary(FSG3)$r.sq
[1] 0.05267319
summary(FSG3)$r.sq
[1] 0.0542546
But there is between projects:
ProjGam <- gam(tot_nparticles~ s(depth, k = 3) + factor(project), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500))
summary(ProjGam)
Family: gaussian
Link function: identity
Formula:
tot_nparticles ~ s(depth, k = 3) + factor(project)
Parametric coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 8.9983 0.4445 20.24 <2e-16 ***
factor(project)P16 17.0001 1.3754 12.36 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Approximate significance of smooth terms:
edf Ref.df F p-value
s(depth) 1 1 3.552 0.064 .
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
R-sq.(adj) = 0.7 Deviance explained = 70.9%
GCV = 12.411 Scale est. = 11.855 n = 67
PlotPSDmany <- uds %>%
filter(project == "ETNP") %>%
ggplot(aes(x = psd, y = depth, shape = factor(day(time)), fill = hour(time))) +
#geom_path(aes(x = psd_gam)) +
#geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1, outline_type = "lower") +
geom_point(alpha = .6, size = 2, stroke = 1) +
scale_y_reverse() + scale_shape_manual(values = c(21:25)) +
scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
labs(x = "Depth (m)", y = "Particle Size Distribution Slope")
PlotParticlesmany <- uds %>%
filter(project == "ETNP") %>%
ggplot(aes(x = tot_nparticles, y = depth, shape = factor(day(time)), fill = hour(time))) +
#geom_path(aes(x = psd_gam)) +
#geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1, outline_type = "lower") +
geom_point(alpha = .6, size = 2, stroke = 1) +
scale_y_reverse() + scale_shape_manual(values = c(21:25)) +
scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
scale_x_log10() + theme(legend.position = "none") +
labs(x = "Depth (m)", y = "Particles / L")
PlotFluxmany <- uds %>%
filter(project == "ETNP") %>%
ggplot(aes(x = tot_flux_fit, y = depth, shape = factor(day(time)), fill = hour(time))) +
#geom_path(aes(x = psd_gam)) +
#geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1, outline_type = "lower") +
geom_point(alpha = .6, size = 2, stroke = 1) +
scale_y_reverse() + scale_shape_manual(values = c(21:25)) +
scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
scale_x_log10() + theme(legend.position = "none")
plot_grid(
PlotParticlesmany,
PlotPSDmany,
rel_widths = c(2, 3)
)

ggsave("figures/ParticlesPSDMany.png")
Saving 12 x 7.41 in image
ggsave("figures/ParticlesPSDMany.svg")
Saving 12 x 7.41 in image
bdsAddTime <- bds %>%
mutate(Hour = hour(time), Day = day(time))
FSG1 <- gam(psd~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
FSG2 <- gam(psd ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
FSG3 <- gam(psd ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
FSG4 <- gam(psd~ s(depth, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
summary(FSG1)
Family: gaussian
Link function: identity
Formula:
psd ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc")
Parametric coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -3.96083 0.01988 -199.3 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Approximate significance of smooth terms:
edf Ref.df F p-value
s(depth) 1.713 1.917 56.197 5.5e-15 ***
s(Day) 1.000 1.000 1.078 0.3036
s(Hour) 1.604 2.000 3.049 0.0285 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
R-sq.(adj) = 0.635 Deviance explained = 66.1%
GCV = 0.026006 Scale est. = 0.023702 n = 60
#summary(FSG2)
#summary(FSG3)
summary(FSG4)
Family: gaussian
Link function: identity
Formula:
psd ~ s(depth, k = 3) + s(Hour, k = 4, bs = "cc")
Parametric coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -3.96083 0.01995 -198.5 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Approximate significance of smooth terms:
edf Ref.df F p-value
s(depth) 1.715 1.919 55.141 7.66e-15 ***
s(Hour) 1.565 2.000 2.497 0.0488 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
R-sq.(adj) = 0.632 Deviance explained = 65.2%
GCV = 0.02572 Scale est. = 0.023885 n = 60
summary(FSG1)$r.sq - summary(FSG2)$r.sq
[1] 0.03804023
summary(FSG2)$r.sq - summary(FSG3)$r.sq
[1] -0.004905911
summary(FSG3)$r.sq
[1] 0.6015425
Not a significant difference in PSD with respect to time.
But there is between projects:
ProjGam <- gam(psd~ s(depth, k = 3) + factor(project), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500))
summary(ProjGam)
Family: gaussian
Link function: identity
Formula:
psd ~ s(depth, k = 3) + factor(project)
Parametric coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -3.96167 0.02491 -159.029 <2e-16 ***
factor(project)P16 -0.19977 0.07708 -2.592 0.0118 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Approximate significance of smooth terms:
edf Ref.df F p-value
s(depth) 1.224 1.398 34.54 2.26e-08 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
R-sq.(adj) = 0.437 Deviance explained = 45.6%
GCV = 0.039117 Scale est. = 0.037234 n = 67
I wonder if I can show that the profiles aren’t statistically significanlty different. Or that they are for that matter… I think in that case, I run a gam with and without a parameter for profile… And then quantify the effect size of that parameter
Or follow this Gavin Simpson Post https://fromthebottomoftheheap.net/2017/10/10/difference-splines-i/
or anova.gam {mgcv}
Calculate gams for each profile, and then run anova.gam to see if they are different…
PlotNParticlesEP <- uds %>%
filter(profile %in% c("stn_043", "p16n_100")) %>%
ggplot(aes(x = tot_nparticles, y = depth, col = project, shape = project)) +
geom_point(alpha = 0.7, size = 2, stroke = 1) +
#geom_path(aes(x = tot_nparticles)) +
#geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1) +
scale_y_reverse(limits = c(2500, 0)) + scale_x_log10() + scale_color_manual(values = c("gray20", "brown")) +
labs(x = "Particles/L", y = "Depth (m)") +
theme(legend.position = "none") +
scale_shape_manual(values = c(1:5))
PlotNParticlesEP

I removed one outlyer from p16 for visualization purposes (300 particles/l at surface)
PlotPSDEP <- uds %>%
filter(profile %in% c("stn_043", "p16n_100")) %>%
ggplot(aes(x = psd, y = depth, col = project, shape = project)) +
geom_point(alpha = 0.7, size = 2, stroke = 1) +
geom_path(aes(x = psd_gam)) +
geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1) +
scale_y_reverse(limits = c(2500, 0)) + scale_color_manual(values = c("gray20", "brown")) +
scale_shape_manual(values = c(1:5)) + labs(y = "", x = "Particle Size Distribution Slope")
PlotPSDEP

I may just cow these togther.
plot_grid(PlotNParticlesEP, PlotPSDEP, rel_widths = c(2,3), labels = c("A", "B"))
Removed 611 rows containing missing values (geom_point).Removed 611 rows containing missing values (geom_point).Removed 611 row(s) containing missing values (geom_path).

ggsave("figures/ParticlesAndPSD_ETNPVsP16.svg")
Saving 10 x 4 in image
ggsave("figures/ParticlesAndPSD_ETNPVsP16.png")
Saving 10 x 4 in image
mainParticleComponents <- bds %>%
filter(profile %in% c("stn_043", "p16n_100")) %>%
select(project, profile, depth,
tot_nparticles, small_nparticles, big_nparticles,
tot_psd = psd, small_psd, big_psd,
tot_flux_fit, small_flux_fit, big_flux_fit) %>%
pivot_longer(cols = -c("project", "profile", "depth")) %>%
separate(name, c("size", "meas")) %>%
mutate(meas = recode(meas, nparticles = "particles/L")) %>%
mutate(meas = factor(meas, levels = c("particles/L", "flux", "psd")))
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘select’ for signature ‘"spec_tbl_df"’
Flux small and flux tot track so closely because ag > psd. since the size distribution of the flux sould be PSD + ag (psd is negative in this case). Yo ucan see the variance at the one depth where psd is flatest at the very top.
eg_dataline <- bds %>%
filter(profile == "stn_043", depth == 162.5)
eg_slope = eg_dataline %>% pull(psd)
eg_icp = eg_dataline %>% pull(icp)
eg_vol = eg_dataline %>% pull(vol)
eg_datablock <- bes %>%
filter(profile == "stn_043", depth == 162.5)
eg_lb = eg_datablock$lb
eg_binsize = eg_datablock$binsize
eg_nnp = exp(eg_icp + log(eg_lb) * eg_slope)
eg_np = eg_nnp * eg_binsize
eg_tp = eg_np * eg_vol
eg_df <- tibble(lb = eg_lb, n_nparticles = eg_nnp, nparticles = eg_np, TotalParticles = eg_tp)
EgNNP <- eg_datablock %>%
ggplot(aes(x = lb, y = n_nparticles)) + geom_point() + scale_x_log10() + scale_y_log10() +
geom_path(data = eg_df) + labs(y = "Binsize & Volume Normalized \n Particles (#/L/mm)", x = "Size (mm)")
EgNP <- eg_datablock %>%
ggplot(aes(x = lb, y = nparticles)) + geom_point() + scale_x_log10() + scale_y_log10() +
geom_path(data = eg_df) + labs(y = "Normalized Particles" , x = "Size (mm)")
EgTP <- eg_datablock %>%
ggplot(aes(x = lb, y = TotalParticles)) + geom_point() + scale_x_log10() + scale_y_log10() +
geom_path(data = eg_df) + labs( y = "Total Particles Observed (#)", x = "Size (mm)")
plot_grid(EgNNP, EgTP, labels = c("A", "B"))
Transformation introduced infinite values in continuous y-axisTransformation introduced infinite values in continuous y-axis
ggsave("figures/ExamplePSD163m.png")
Saving 7.29 x 4.5 in image
ggsave("figures/ExamplePSD163m.svg")
Saving 7.29 x 4.5 in image

Smooth flux and um disaggregation.
bds %>%
ggplot(aes(y = depth, x = Flux_Smooth, col = factor(time))) + facet_wrap(~project) + geom_point() + scale_y_reverse(limits = c(1000, 0)) + scale_x_log10()

bdsAddTime <- bds %>%
mutate(Hour = hour(time), Day = day(time))
FSG1 <- gam(Flux_Smooth~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
FSG2 <- gam(Flux_Smooth ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
FSG3 <- gam(Flux_Smooth ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
summary(FSG1)
Family: gaussian
Link function: identity
Formula:
Flux_Smooth ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4,
bs = "cc")
Parametric coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 34.7319 0.9174 37.86 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Approximate significance of smooth terms:
edf Ref.df F p-value
s(depth) 1.878 1.985 12.389 8.56e-05 ***
s(Day) 1.881 1.985 3.235 0.0416 *
s(Hour) 1.454 2.000 2.926 0.0233 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
R-sq.(adj) = 0.352 Deviance explained = 41%
GCV = 56.33 Scale est. = 50.497 n = 60
summary(FSG2)
Family: gaussian
Link function: identity
Formula:
Flux_Smooth ~ s(depth, k = 3) + s(Day, k = 3)
Parametric coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 34.7319 0.9663 35.94 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Approximate significance of smooth terms:
edf Ref.df F p-value
s(depth) 1.867 1.982 11.055 0.000216 ***
s(Day) 1.814 1.965 2.125 0.128023
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
R-sq.(adj) = 0.282 Deviance explained = 32.6%
GCV = 60.77 Scale est. = 56.029 n = 60
summary(FSG3)
Family: gaussian
Link function: identity
Formula:
Flux_Smooth ~ s(depth, k = 3)
Parametric coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 34.7319 0.9944 34.93 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Approximate significance of smooth terms:
edf Ref.df F p-value
s(depth) 1.857 1.979 10.73 0.000277 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
R-sq.(adj) = 0.239 Deviance explained = 26.3%
GCV = 62.291 Scale est. = 59.325 n = 60
summary(FSG1)$r.sq - summary(FSG2)$r.sq
[1] 0.0709392
summary(FSG2)$r.sq - summary(FSG3)$r.sq
[1] 0.04226961
summary(FSG3)$r.sq
[1] 0.2392424
bds %>% filter(project == "ETNP") %>% select(profile, depth, Flux_Smooth) %>% pivot_wider(names_from = profile, values_from = Flux_Smooth)
Something is off. All of the flux profiles are identical. Skip this
cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
plt1 <- bds %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
ggplot(aes(y = depth, x = DFP, col = factor(time), shape = factor(time))) + facet_wrap(~project) + geom_point() + scale_y_reverse(limits = c(1000, 0)) + xlim(c(0.5, 1.5))+ geom_vline(xintercept = 1) +
scale_color_manual(values = c(rep("black", 5), rep("blue", 5))) + scale_shape_manual(values = rep(1:5, 2))
plotly::ggplotly(plt1)
What the heck is going on with DFP here. Why is it usually > 1 shouldn’t it be less than 1 when flux is decreasing? This very deep increasing flux seems improbable to me. Lets check the smooths. Or only go to 1000m.
, legend.background = element_blank(), legend.box.background = element_rect()
scientific_10 <- function(x) {parse(text=gsub("e\\+*", " %*% 10^", scales::scientific_format()(x))) }
#https://stackoverflow.com/questions/10762287/how-can-i-format-axis-labels-with-exponents-with-ggplot2-and-scales
#jacob_magnitude <- function(x){expression(10^round(log10(x)))}
cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltFlx <- bds %>% filter(project == "ETNP") %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
ggplot(aes(y = depth, x = Flux_Smooth, shape = factor(day(time)), fill = hour(time), group = factor(time))) + geom_point(size = 3, stroke = 1)+
geom_path() +
scale_y_reverse(limits = c(1000, 0))+
scale_x_log10(label = scientific_10) +
scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) +
scale_fill_gradientn(name = "Hour of Day", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
labs(x = bquote(Smoothed~Flux~(µmol~C/m^2/d)), y = "Depth (m)") +
geom_rect(data = data.frame(project = "ETNP"), aes(xmin = 20, xmax = 180, ymin = 75, ymax = 500), colour = "red", fill = NA, inherit.aes = FALSE) +
theme(axis.text.x = element_text(angle = 90, vjust = .3), legend.spacing = unit(.1, "cm"))
pltFlxNoLegend <- pltFlx + theme(legend.position = "none")
pltFlxLegend <- get_legend(pltFlx)
Removed 14 rows containing missing values (geom_point).Removed 14 row(s) containing missing values (geom_path).
pltFlx

#plotly::ggplotly(plt1)
cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltFlxZoom <- bds %>% filter(project == "ETNP" & depth <= 500 & depth >= 75) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
ggplot(aes(y = depth, x = Flux_Smooth, shape = factor(day(time)), fill = hour(time), group = factor(time))) + geom_point(size = 3, stroke = 1)+
geom_path() +
scale_y_reverse()+
#scale_x_log10() +
scale_x_log10(breaks = c(seq(from = 20, to = 50, by = 10), seq(from = 60, to = 180, by = 20)), limits = c(20, 180)) +
scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(values = rep(21:25, 2)) +
scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
theme(axis.text.x = element_text(angle = 90)) +
labs(x = "Smoothed Flux", y = "Depth") + theme(legend.position = "none")
pltFlxZoom

#plotly::ggplotly(plt1)
cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltDelta3 <- bds %>% filter(project == "ETNP") %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
ggplot(aes(y = depth, x = pracma::nthroot(DF/DZ, 5), shape = factor(day(time)), fill = hour(time), group = factor(time))) + geom_point(size = 3, stroke = 1)+
geom_path() +
scale_y_reverse(limits = c(1000, 0))+
scale_x_continuous(limits = c(-2.1, .6), breaks = seq(from = -2, to = .75, by = 0.5)) +
#scale_x_log10() +
scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) +
scale_fill_gradientn(name = "Hour", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
geom_vline(xintercept = 0) +
labs(x = bquote((DF/DZ)^{1/5}~(µmolC/m^3/d)^{1/5}), y = "Depth (m)") + theme(legend.pos = "none")
#labs(x = "(DF/DZ) ^ 1/5 (µmol C/m^3/d) ^ 1/5")
pltDelta3

#plotly::ggplotly(plt1pos)
# #plot_grid(pltFlxNoLegend, pltFlxZoom, pltDelta3, pltFlxLegend)
#
# pltFlxLegend <- get_legend(pltFlx + theme(legend.box.margin = margin(0, 0, 40, 10)))
#
# pgTop <- plot_grid(pltFlxNoLegend, pltFlxZoom + theme(plot.margin = unit(c(1, 0, 3, 0), units = "cm")), rel_widths = c(2, 1), labels = c("A", "B"))
# pgBottom <- plot_grid(pltDelta3, pltFlxLegend , rel_widths = c(3, 1), labels = c("C", ""), label_size = 14)
# pgBoth <- plot_grid(pgTop, pgBottom, ncol = 1)
#
# pgBoth
#
# ggsave("figures/FluxDeepDive.png")
# ggsave("figures/FluxDeepDive.svg")
Within panel drawing
pgTop <- ggdraw(pltFlxNoLegend
) +
draw_plot(pltFlxZoom, .4, .25, .55, .60) +
draw_plot_label(
c("","B"),
c(.05, 0.55),
c(1, 0.85),
size = 16
)
Removed 14 rows containing missing values (geom_point).Removed 14 row(s) containing missing values (geom_path).
pgTop

pgBottom <- plot_grid(pltDelta3, pltFlxLegend , rel_widths = c(3, 1), labels = c(“C”, ""), label_size = 14)
I don’t know whats going on below here
pgBottom <- pltDelta3 + geom_rect(aes(xmin = -2, xmax = -1.15, ymin = 170, ymax = 1000), colour = "gray50", fill = NA, inherit.aes = FALSE) + draw_plot(pltFlxLegend , -1.9, -575, .7)
pgBoth <- plot_grid(pgTop + theme(plot.margin = unit(c(0, 0, 0, 0), units = "cm")),
pgBottom + theme(plot.margin = unit(c(0, 0, 0, 0), units = "cm")),
ncol = 1, rel_heights = c(4, 4), labels = c("A", "C"), label_size = 16)
Removed 33 rows containing missing values (geom_point).Removed 33 row(s) containing missing values (geom_path).
pgBoth

ggsave("figures/FluxDeepDive.png")
Saving 5 x 9 in image
ggsave("figures/FluxDeepDive.svg")
Saving 5 x 9 in image
# #plot_grid(pltFlxNoLegend, pltFlxZoom, pltDelta3, pltFlxLegend)
#
# pltFlxLegend <- get_legend(pltFlx + theme(legend.box.margin = margin(0, 0, 40, 10)))
#
# pgTop <- plot_grid(pltFlxNoLegend + ylim(c(1000, 0)), pltFlxZoom + theme(plot.margin = unit(c(1, 0, 3, 0), units = "cm")), rel_widths = c(2, 1), labels = c("A", "B"))
# pgBottom <- plot_grid(pltDelta3 + ylim(c(1000, 0)), pltFlxLegend , rel_widths = c(3, 1), labels = c("C", ""))
# pgBoth <- plot_grid(pgTop, pgBottom, ncol = 1)
#
# pgBoth
#
# #ggsave("figures/FluxShallowDive.png")
# #ggsave("figures/FluxShallowDive.svg")
Test for day to day and hourly variability
bdsAddTime <- bds %>%
mutate(Hour = hour(time), Day = day(time))
DFG1 <- gam(DF/DZ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
DFG2 <- gam(DF/DZ ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
DFG3 <- gam(DF/DZ ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
summary(DFG1)
Family: gaussian
Link function: identity
Formula:
DF/DZ ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc")
Parametric coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.1001 0.0173 -5.785 3.8e-07 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Approximate significance of smooth terms:
edf Ref.df F p-value
s(depth) 1.907 1.991 22.926 8.57e-08 ***
s(Day) 1.908 1.991 6.576 0.00212 **
s(Hour) 1.329 2.000 2.351 0.03593 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
R-sq.(adj) = 0.502 Deviance explained = 54.5%
GCV = 0.020011 Scale est. = 0.017961 n = 60
summary(DFG2)
Family: gaussian
Link function: identity
Formula:
DF/DZ ~ s(depth, k = 3) + s(Day, k = 3)
Parametric coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.10008 0.01804 -5.547 8.5e-07 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Approximate significance of smooth terms:
edf Ref.df F p-value
s(depth) 1.897 1.989 21.470 2.11e-07 ***
s(Day) 1.903 1.991 4.847 0.00988 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
R-sq.(adj) = 0.458 Deviance explained = 49.3%
GCV = 0.021234 Scale est. = 0.019535 n = 60
summary(DFG3)
Family: gaussian
Link function: identity
Formula:
DF/DZ ~ s(depth, k = 3)
Parametric coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.10008 0.01944 -5.149 3.37e-06 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Approximate significance of smooth terms:
edf Ref.df F p-value
s(depth) 1.878 1.985 19.24 9.12e-07 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
R-sq.(adj) = 0.371 Deviance explained = 39.1%
GCV = 0.023812 Scale est. = 0.02267 n = 60
summary(DFG1)$r.sq - summary(DFG2)$r.sq
[1] 0.04364864
summary(DFG2)$r.sq - summary(DFG3)$r.sq
[1] 0.08693722
summary(DFG3)$r.sq
[1] 0.3713016
png(filename = “./figures/CombinedP2Info.png”, width = 10, height = 8, units = “in”, res = 200) StationInfoPlot() dev.off()
#plot.new()
FluxGamPlot <- function(){
par(mfrow = c(2,2))
plot(DFG1)
mtext(expression(bold("C")), side = 3, line = 0, adj = 0, cex = 2)
par(mfg = c(1,1))
mtext(expression(bold("A")), side = 3, line = 0, adj = 0, cex = 2)
par(mfg = c(1,2))
mtext(expression(bold("B")), side = 3, line = 0, adj = 0, cex = 2)
}
FluxGamPlot()
png(filename = "./figures/FluxGamPlot.png", width = 10, height = 8, units = "in", res = 200)
FluxGamPlot()
dev.off()
png
2

#Osps
(u mol C / m^3 / day)
bds %>% filter(project == "ETNP") %>%
ggplot(aes(y = depth, x = pracma::nthroot(ospsDZ, 3), shape = factor(day(time)), fill = hour(time), group = factor(time))) + geom_point(size = 2) + scale_y_reverse(limits = c(1000, 0)) +
scale_x_continuous(limits = c(-1, 1)) +
geom_vline(xintercept = 0) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + labs(x = bquote("Observed - Modeled Small Particle Flux"~(μmol/m^3/day))) +
scale_fill_gradientn(name = "Hour of Day", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) + geom_hline(yintercept = 175, color = "darkgreen") + geom_hline(yintercept = 950, color = "darkblue")

#ggsave("..figures/FluxSizeShift.svg"
ggsave("figures/FluxSizeShift.png")
Saving 6 x 4 in image
ggsave("figures/FluxSizeShift.svg")
Saving 6 x 4 in image
bdsAddTime <- bds %>%
mutate(Hour = hour(time), Day = day(time))
OZG1 <- gam(ospsDZ ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
OZG2 <- gam(ospsDZ ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
OZG3 <- gam(ospsDZ ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))
summary(OZG1)
Family: gaussian
Link function: identity
Formula:
ospsDZ ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc")
Parametric coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.024817 0.002255 11.01 1.77e-15 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Approximate significance of smooth terms:
edf Ref.df F p-value
s(depth) 1.8900 1.988 8.511 0.000405 ***
s(Day) 1.9131 1.992 6.058 0.003482 **
s(Hour) 0.5495 2.000 0.407 0.235090
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
R-sq.(adj) = 0.341 Deviance explained = 39%
GCV = 0.00033503 Scale est. = 0.00030514 n = 60
summary(OZG2)
Family: gaussian
Link function: identity
Formula:
ospsDZ ~ s(depth, k = 3) + s(Day, k = 3)
Parametric coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.024817 0.002272 10.92 2.06e-15 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Approximate significance of smooth terms:
edf Ref.df F p-value
s(depth) 1.889 1.988 8.417 0.000432 ***
s(Day) 1.910 1.992 5.671 0.004881 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
R-sq.(adj) = 0.331 Deviance explained = 37.4%
GCV = 0.00033672 Scale est. = 0.00030979 n = 60
summary(OZG3)
Family: gaussian
Link function: identity
Formula:
ospsDZ ~ s(depth, k = 3)
Parametric coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.024817 0.002479 10.01 3.55e-14 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Approximate significance of smooth terms:
edf Ref.df F p-value
s(depth) 1.872 1.984 7.338 0.000983 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
R-sq.(adj) = 0.204 Deviance explained = 22.9%
GCV = 0.00038738 Scale est. = 0.00036884 n = 60
summary(OZG1)$r.sq - summary(OZG2)$r.sq
[1] 0.01003818
summary(OZG2)$r.sq - summary(OZG3)$r.sq
[1] 0.1274581
summary(OZG3)$r.sq
[1] 0.2038316
OSMSGamPlot <- function(){
par(mfrow = c(1,2))
plot(OZG2)
mtext(expression(bold("B")), side = 3, line = 0, adj = 0, cex = 2)
par(mfg = c(1,1))
mtext(expression(bold("A")), side = 3, line = 0, adj = 0, cex = 2)
}
OSMSGamPlot()
png(filename = "./figures/OSMSGamPlot.png", width = 10, height = 6, units = "in", res = 200)
OSMSGamPlot()
dev.off()
png
2

bds %>% filter(project == "P16") %>%
ggplot(aes(y = depth, x = ospsDZ)) + facet_wrap(~project) + geom_point() + scale_y_reverse(limits = c(500, 0)) + geom_vline(xintercept = 0)
Error in eval(lhs, parent, parent) : object 'bds' not found
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KG1nY3YpCnNvdXJjZSgiVVZQXzIwMTdfbGlicmFyeS5SIikKdGhlbWVfc2V0KHRoZW1lX2Nvd3Bsb3QoKSkKY2IxMCA8LSBjKCcjYTZjZWUzJywnIzFmNzhiNCcsJyNiMmRmOGEnLCcjMzNhMDJjJywnI2ZiOWE5OScsJyNlMzFhMWMnLCcjZmRiZjZmJywnI2ZmN2YwMCcsJyNjYWIyZDYnLCcjNmEzZDlhJykKYGBgCgoKIyBQYXJ0aWNsZXMgT25seQoKIyBSZWFkIEluIERhdGEKCmBgYHtyfQpiZXM8LSByZWFkX2NzdigiZGF0YU91dC9iaW5uZWRfRWFjaFNpemUuY3N2IikKYmRzIDwtIHJlYWRfY3N2KCJkYXRhT3V0L2Jpbm5lZF9EZXB0aFN1bW1hcnkuY3N2IikKdWVzIDwtIHJlYWRfY3N2KCJkYXRhT3V0L3VuYmlubmVkX0VhY2hTaXplLmNzdiIpCnVkcyA8LSByZWFkX2NzdigiZGF0YU91dC91bmJpbm5lZF9EZXB0aFN1bW1hcnkuY3N2IikKYGBgCgpgYGB7cn0KUGhvdGljQmFzZSA8LSAxNjAKT01aQmFzZSA8LSA4NTAKYGBgCgoKIyBTdW1tYXJ5IFN0YXRpc3RpY3MKYGBge3J9ClBsb3ROUGFydGljbGVzIDwtIHVkcyAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gdG90X25wYXJ0aWNsZXMsIHkgPSBkZXB0aCwgY29sID0gcHJvZmlsZSkpICsKIGZhY2V0X3dyYXAofnByb2plY3QpICsKIGdlb21fcG9pbnQoYWxwaGEgPSAwLjMsIHNoYXBlID0gMSkgKwpzY2FsZV95X3JldmVyc2UoKSArIHNjYWxlX3hfbG9nMTAoKQoKUGxvdE5QYXJ0aWNsZXMKYGBgCgpgYGB7cn0KYmRzQWRkVGltZSA8LSBiZHMgJT4lCiAgbXV0YXRlKEhvdXIgPSBob3VyKHRpbWUpLCBEYXkgPSBkYXkodGltZSkpCgpGU0cxIDwtIGdhbSh0b3RfbnBhcnRpY2xlc34gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSArIHMoSG91ciwgayA9IDQsIGJzID0gImNjIiksIGtub3RzID0gbGlzdChIb3VyID0gYygwLCAyNCkpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHMiA8LSBnYW0odG90X25wYXJ0aWNsZXMgfiBzKGRlcHRoLCBrID0gMykgKyBzKERheSwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHMyA8LSBnYW0odG90X25wYXJ0aWNsZXMgfiBzKGRlcHRoLCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgojRlNHNCA8LSBnYW0odG90X25wYXJ0aWNsZXN+IHMoZGVwdGgsIGsgPSAzKSAgKyBzKEhvdXIsIGsgPSA0LCBicyA9ICJjYyIpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCnN1bW1hcnkoRlNHMSkKI3N1bW1hcnkoRlNHMikKI3N1bW1hcnkoRlNHMykKI3N1bW1hcnkoRlNHNCkKCnN1bW1hcnkoRlNHMSkkci5zcSAtIHN1bW1hcnkoRlNHMikkci5zcQpzdW1tYXJ5KEZTRzIpJHIuc3EgLSBzdW1tYXJ5KEZTRzMpJHIuc3EKc3VtbWFyeShGU0czKSRyLnNxCmBgYAoKQnV0IHRoZXJlIGlzIGJldHdlZW4gcHJvamVjdHM6CmBgYHtyfQpQcm9qR2FtIDwtIGdhbSh0b3RfbnBhcnRpY2xlc34gcyhkZXB0aCwgayA9IDMpICsgZmFjdG9yKHByb2plY3QpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCkpCgpzdW1tYXJ5KFByb2pHYW0pCmBgYAoKYGBge3IgZmlnLndpZHRoID0gMTJ9ClBsb3RQU0RtYW55IDwtIHVkcyAlPiUgCiAgZmlsdGVyKHByb2plY3QgPT0gIkVUTlAiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBwc2QsIHkgPSBkZXB0aCwgc2hhcGUgPSBmYWN0b3IoZGF5KHRpbWUpKSwgZmlsbCA9IGhvdXIodGltZSkpKSArCiAKICAjZ2VvbV9wYXRoKGFlcyh4ID0gcHNkX2dhbSkpICsgCiAgI2dlb21fcmliYm9uKGFlcyh4ID0gcHNkX2dhbSwgeG1pbiA9IHBzZF9nYW0gLSAyICogcHNkX3NlZywgeG1heCA9IHBzZF9nYW0gKyAyICogcHNkX3NlZyksIGFscGhhID0gMC4xLCBvdXRsaW5lX3R5cGUgPSAibG93ZXIiKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IC42LCBzaXplID0gMiwgc3Ryb2tlID0gMSkgKwogIHNjYWxlX3lfcmV2ZXJzZSgpICsgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMjE6MjUpKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudG4oYnJlYWtzID0gYygwLCA2LCAxMiwgMTgsIDI0KSwgY29sb3JzID0gYygiYmxhY2siLCAiYmx1ZSIsICJ3aGl0ZSIsICJvcmFuZ2UiLCAiYmxhY2siKSkgKwogIGxhYnMoeCA9ICJEZXB0aCAobSkiLCB5ID0gIlBhcnRpY2xlIFNpemUgRGlzdHJpYnV0aW9uIFNsb3BlIikKClBsb3RQYXJ0aWNsZXNtYW55IDwtIHVkcyAlPiUgCiAgZmlsdGVyKHByb2plY3QgPT0gIkVUTlAiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB0b3RfbnBhcnRpY2xlcywgeSA9IGRlcHRoLCBzaGFwZSA9IGZhY3RvcihkYXkodGltZSkpLCBmaWxsID0gaG91cih0aW1lKSkpICsKIAogICNnZW9tX3BhdGgoYWVzKHggPSBwc2RfZ2FtKSkgKyAKICAjZ2VvbV9yaWJib24oYWVzKHggPSBwc2RfZ2FtLCB4bWluID0gcHNkX2dhbSAtIDIgKiBwc2Rfc2VnLCB4bWF4ID0gcHNkX2dhbSArIDIgKiBwc2Rfc2VnKSwgYWxwaGEgPSAwLjEsIG91dGxpbmVfdHlwZSA9ICJsb3dlciIpICsKICBnZW9tX3BvaW50KGFscGhhID0gLjYsIHNpemUgPSAyLCBzdHJva2UgPSAxKSArCiAgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygyMToyNSkpICsKICBzY2FsZV9maWxsX2dyYWRpZW50bihicmVha3MgPSBjKDAsIDYsIDEyLCAxOCwgMjQpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpKSArCiAgc2NhbGVfeF9sb2cxMCgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgbGFicyh4ID0gIkRlcHRoIChtKSIsIHkgPSAiUGFydGljbGVzIC8gTCIpCgpQbG90Rmx1eG1hbnkgPC0gdWRzICU+JSAKICBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIpICU+JQogIGdncGxvdChhZXMoeCA9IHRvdF9mbHV4X2ZpdCwgeSA9IGRlcHRoLCBzaGFwZSA9IGZhY3RvcihkYXkodGltZSkpLCBmaWxsID0gaG91cih0aW1lKSkpICsKIAogICNnZW9tX3BhdGgoYWVzKHggPSBwc2RfZ2FtKSkgKyAKICAjZ2VvbV9yaWJib24oYWVzKHggPSBwc2RfZ2FtLCB4bWluID0gcHNkX2dhbSAtIDIgKiBwc2Rfc2VnLCB4bWF4ID0gcHNkX2dhbSArIDIgKiBwc2Rfc2VnKSwgYWxwaGEgPSAwLjEsIG91dGxpbmVfdHlwZSA9ICJsb3dlciIpICsKICBnZW9tX3BvaW50KGFscGhhID0gLjYsIHNpemUgPSAyLCBzdHJva2UgPSAxKSArCiAgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygyMToyNSkpICsKICBzY2FsZV9maWxsX2dyYWRpZW50bihicmVha3MgPSBjKDAsIDYsIDEyLCAxOCwgMjQpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpKSArCiAgc2NhbGVfeF9sb2cxMCgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKCgpwbG90X2dyaWQoCiAgUGxvdFBhcnRpY2xlc21hbnksCiAgUGxvdFBTRG1hbnksCiAgcmVsX3dpZHRocyA9IGMoMiwgMykKICApCgpnZ3NhdmUoImZpZ3VyZXMvUGFydGljbGVzUFNETWFueS5wbmciKQpnZ3NhdmUoImZpZ3VyZXMvUGFydGljbGVzUFNETWFueS5zdmciKQoKYGBgCgpgYGB7cn0KYmRzQWRkVGltZSA8LSBiZHMgJT4lCiAgbXV0YXRlKEhvdXIgPSBob3VyKHRpbWUpLCBEYXkgPSBkYXkodGltZSkpCgpGU0cxIDwtIGdhbShwc2R+IHMoZGVwdGgsIGsgPSAzKSArIHMoRGF5LCBrID0gMykgKyBzKEhvdXIsIGsgPSA0LCBicyA9ICJjYyIpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCkZTRzIgPC0gZ2FtKHBzZCB+IHMoZGVwdGgsIGsgPSAzKSArIHMoRGF5LCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpGU0czIDwtIGdhbShwc2QgfiBzKGRlcHRoLCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpGU0c0IDwtIGdhbShwc2R+IHMoZGVwdGgsIGsgPSAzKSAgKyBzKEhvdXIsIGsgPSA0LCBicyA9ICJjYyIpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCnN1bW1hcnkoRlNHMSkKI3N1bW1hcnkoRlNHMikKI3N1bW1hcnkoRlNHMykKc3VtbWFyeShGU0c0KQoKc3VtbWFyeShGU0cxKSRyLnNxIC0gc3VtbWFyeShGU0cyKSRyLnNxCnN1bW1hcnkoRlNHMikkci5zcSAtIHN1bW1hcnkoRlNHMykkci5zcQpzdW1tYXJ5KEZTRzMpJHIuc3EKYGBgCk5vdCBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gUFNEIHdpdGggcmVzcGVjdCB0byB0aW1lLgoKQnV0IHRoZXJlIGlzIGJldHdlZW4gcHJvamVjdHM6CmBgYHtyfQpQcm9qR2FtIDwtIGdhbShwc2R+IHMoZGVwdGgsIGsgPSAzKSArIGZhY3Rvcihwcm9qZWN0KSwga25vdHMgPSBsaXN0KEhvdXIgPSBjKDAsIDI0KSksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDApKQoKc3VtbWFyeShQcm9qR2FtKQpgYGAKCgoKCkkgd29uZGVyIGlmIEkgY2FuIHNob3cgdGhhdCB0aGUgcHJvZmlsZXMgYXJlbid0IHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbmx0eSBkaWZmZXJlbnQuIE9yIHRoYXQgdGhleSBhcmUgZm9yIHRoYXQgbWF0dGVyLi4uCkkgdGhpbmsgaW4gdGhhdCBjYXNlLCBJIHJ1biBhIGdhbSB3aXRoIGFuZCB3aXRob3V0IGEgcGFyYW1ldGVyIGZvciBwcm9maWxlLi4uCkFuZCB0aGVuIHF1YW50aWZ5IHRoZSBlZmZlY3Qgc2l6ZSBvZiB0aGF0IHBhcmFtZXRlcgoKT3IgZm9sbG93IHRoaXMgR2F2aW4gU2ltcHNvbiBQb3N0Cmh0dHBzOi8vZnJvbXRoZWJvdHRvbW9mdGhlaGVhcC5uZXQvMjAxNy8xMC8xMC9kaWZmZXJlbmNlLXNwbGluZXMtaS8KCm9yIAphbm92YS5nYW0ge21nY3Z9CgpDYWxjdWxhdGUgZ2FtcyBmb3IgZWFjaCBwcm9maWxlLCBhbmQgdGhlbiBydW4gYW5vdmEuZ2FtIHRvIHNlZSBpZiB0aGV5IGFyZSBkaWZmZXJlbnQuLi4KCmBgYHtyfQpQbG90TlBhcnRpY2xlc0VQIDwtIHVkcyAlPiUgCiAgZmlsdGVyKHByb2ZpbGUgJWluJSBjKCJzdG5fMDQzIiwgInAxNm5fMTAwIikpICU+JQogIGdncGxvdChhZXMoeCA9IHRvdF9ucGFydGljbGVzLCB5ID0gZGVwdGgsIGNvbCA9IHByb2plY3QsIHNoYXBlID0gcHJvamVjdCkpICsKIGdlb21fcG9pbnQoYWxwaGEgPSAwLjcsIHNpemUgPSAyLCBzdHJva2UgPSAxKSArCiAgI2dlb21fcGF0aChhZXMoeCA9IHRvdF9ucGFydGljbGVzKSkgKwogICNnZW9tX3JpYmJvbihhZXMoeCA9IHBzZF9nYW0sIHhtaW4gPSBwc2RfZ2FtIC0gMiAqIHBzZF9zZWcsIHhtYXggPSBwc2RfZ2FtICsgMiAqIHBzZF9zZWcpLCBhbHBoYSA9IDAuMSkgKwpzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygyNTAwLCAwKSkgKyBzY2FsZV94X2xvZzEwKCkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiZ3JheTIwIiwgImJyb3duIikpICsKICBsYWJzKHggPSAiUGFydGljbGVzL0wiLCB5ID0gIkRlcHRoIChtKSIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygxOjUpKSAKClBsb3ROUGFydGljbGVzRVAKYGBgCgpJIHJlbW92ZWQgb25lIG91dGx5ZXIgZnJvbSBwMTYgZm9yIHZpc3VhbGl6YXRpb24gcHVycG9zZXMgKDMwMCBwYXJ0aWNsZXMvbCBhdCBzdXJmYWNlKQoKYGBge3J9ClBsb3RQU0RFUCA8LSB1ZHMgJT4lIAogIGZpbHRlcihwcm9maWxlICVpbiUgYygic3RuXzA0MyIsICJwMTZuXzEwMCIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBwc2QsIHkgPSBkZXB0aCwgY29sID0gcHJvamVjdCwgc2hhcGUgPSBwcm9qZWN0KSkgKwogZ2VvbV9wb2ludChhbHBoYSA9IDAuNywgc2l6ZSA9IDIsIHN0cm9rZSA9IDEpICsKICBnZW9tX3BhdGgoYWVzKHggPSBwc2RfZ2FtKSkgKwogIGdlb21fcmliYm9uKGFlcyh4ID0gcHNkX2dhbSwgeG1pbiA9IHBzZF9nYW0gLSAyICogcHNkX3NlZywgeG1heCA9IHBzZF9nYW0gKyAyICogcHNkX3NlZyksIGFscGhhID0gMC4xKSArCnNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDI1MDAsIDApKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJncmF5MjAiLCAiYnJvd24iKSkgICsKICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygxOjUpKSArIGxhYnMoeSA9ICIiLCB4ID0gIlBhcnRpY2xlIFNpemUgRGlzdHJpYnV0aW9uIFNsb3BlIikKClBsb3RQU0RFUApgYGAKCkkgbWF5IGp1c3QgY293IHRoZXNlIHRvZ3RoZXIuCgpgYGB7ciBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDR9CnBsb3RfZ3JpZChQbG90TlBhcnRpY2xlc0VQLCBQbG90UFNERVAsIHJlbF93aWR0aHMgPSBjKDIsMyksIGxhYmVscyA9IGMoIkEiLCAiQiIpKQpnZ3NhdmUoImZpZ3VyZXMvUGFydGljbGVzQW5kUFNEX0VUTlBWc1AxNi5zdmciKQpnZ3NhdmUoImZpZ3VyZXMvUGFydGljbGVzQW5kUFNEX0VUTlBWc1AxNi5wbmciKQpgYGAKCmBgYHtyfQptYWluUGFydGljbGVDb21wb25lbnRzIDwtIGJkcyAlPiUKICBmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgc2VsZWN0KHByb2plY3QsIHByb2ZpbGUsIGRlcHRoLAogICAgICAgICB0b3RfbnBhcnRpY2xlcywgc21hbGxfbnBhcnRpY2xlcywgYmlnX25wYXJ0aWNsZXMsCiAgICAgICAgIHRvdF9wc2QgPSBwc2QsIHNtYWxsX3BzZCwgYmlnX3BzZCwKICAgICAgICAgdG90X2ZsdXhfZml0LCBzbWFsbF9mbHV4X2ZpdCwgYmlnX2ZsdXhfZml0KSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IC1jKCJwcm9qZWN0IiwgInByb2ZpbGUiLCAiZGVwdGgiKSkgJT4lCiAgc2VwYXJhdGUobmFtZSwgYygic2l6ZSIsICJtZWFzIikpICU+JQogIG11dGF0ZShtZWFzID0gcmVjb2RlKG1lYXMsIG5wYXJ0aWNsZXMgPSAicGFydGljbGVzL0wiKSkgJT4lCiAgbXV0YXRlKG1lYXMgPSBmYWN0b3IobWVhcywgbGV2ZWxzID0gYygicGFydGljbGVzL0wiLCAiZmx1eCIsICJwc2QiKSkpCgpQbG90Rmx4IDwtIG1haW5QYXJ0aWNsZUNvbXBvbmVudHMgJT4lIAogIGZpbHRlcihtZWFzICE9ICJwc2QiKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCwgeCA9IHZhbHVlLCBjb2wgPSBwcm9qZWN0LCBzaGFwZSA9IHByb2plY3QpKSArIGZhY2V0X2dyaWQoc2l6ZSB+IG1lYXMsIHNjYWxlcyA9ICJmcmVlX3giKSArIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpICsgc2NhbGVfeF9sb2cxMCgpICsgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIHN0cmlwLmJhY2tncm91bmQueSA9IGVsZW1lbnRfYmxhbmsoKSwgc3RyaXAudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCBwbG90Lm1hcmdpbiA9IHVuaXQoYyg3LDAsNyw3KSwgInB0IikpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImJyb3duIiwgImdyYXkyMCIpKSArIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE6NSkpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKQoKUGxvdFBTRCA8LSBtYWluUGFydGljbGVDb21wb25lbnRzICU+JSAKICBmaWx0ZXIobWVhcyA9PSAicHNkIikgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSB2YWx1ZSwgY29sID0gcHJvamVjdCwgc2hhcGUgPSBwcm9qZWN0KSkgKyBmYWNldF9ncmlkKHNpemV+bWVhcywgc2NhbGVzID0gImZyZWVfeCIpICsgZ2VvbV9wb2ludChzaXplID0gMikgKyBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwgcGxvdC5tYXJnaW4gPSB1bml0KGMoNyw3LDI2LjUsMCksICJwdCIpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImJyb3duIiwgImdyYXkyMCIpKSArICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygxOjUpKSArICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNzUsIGNvbG9yID0gImRhcmtncmVlbiIpCgpwbG90X2dyaWQoUGxvdEZseCwgUGxvdFBTRCwgcmVsX3dpZHRocyA9IGMoMywgMikpCgpnZ3NhdmUoImZpZ3VyZXMvQmlnVnNTbWFsbC5zdmciKQpnZ3NhdmUoImZpZ3VyZXMvQmlnVnNTbWFsbC5wbmciKQpgYGAKCkZsdXggc21hbGwgYW5kIGZsdXggdG90IHRyYWNrIHNvIGNsb3NlbHkgYmVjYXVzZSBhZyA+IHBzZC4gc2luY2UgdGhlIHNpemUgZGlzdHJpYnV0aW9uIG9mIHRoZSBmbHV4IHNvdWxkIGJlIFBTRCArIGFnIChwc2QgaXMgbmVnYXRpdmUgaW4gdGhpcyBjYXNlKS4gWW8gdWNhbiBzZWUgdGhlIHZhcmlhbmNlIGF0IHRoZSBvbmUgZGVwdGggd2hlcmUgcHNkIGlzIGZsYXRlc3QgYXQgdGhlIHZlcnkgdG9wLgoKYGBge3J9CmVnX2RhdGFsaW5lIDwtIGJkcyAlPiUgCiAgZmlsdGVyKHByb2ZpbGUgPT0gInN0bl8wNDMiLCBkZXB0aCA9PSAxNjIuNSkKZWdfc2xvcGUgPSAgZWdfZGF0YWxpbmUgJT4lIHB1bGwocHNkKQplZ19pY3AgPSBlZ19kYXRhbGluZSAlPiUgcHVsbChpY3ApCmVnX3ZvbCA9IGVnX2RhdGFsaW5lICU+JSBwdWxsKHZvbCkKCmVnX2RhdGFibG9jayA8LSBiZXMgJT4lCiAgZmlsdGVyKHByb2ZpbGUgPT0gInN0bl8wNDMiLCBkZXB0aCA9PSAxNjIuNSkKCgplZ19sYiA9IGVnX2RhdGFibG9jayRsYgplZ19iaW5zaXplID0gZWdfZGF0YWJsb2NrJGJpbnNpemUKZWdfbm5wID0gZXhwKGVnX2ljcCArIGxvZyhlZ19sYikgKiBlZ19zbG9wZSkKCmVnX25wID0gZWdfbm5wICogZWdfYmluc2l6ZQplZ190cCA9IGVnX25wICogZWdfdm9sCmVnX2RmIDwtIHRpYmJsZShsYiA9IGVnX2xiLCBuX25wYXJ0aWNsZXMgPSBlZ19ubnAsIG5wYXJ0aWNsZXMgPSBlZ19ucCwgVG90YWxQYXJ0aWNsZXMgPSBlZ190cCkKCgpFZ05OUCA8LSBlZ19kYXRhYmxvY2sgJT4lCiAgZ2dwbG90KGFlcyh4ID0gbGIsIHkgPSBuX25wYXJ0aWNsZXMpKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX3lfbG9nMTAoKSArIAogIGdlb21fcGF0aChkYXRhID0gZWdfZGYpICsgbGFicyh5ID0gIkJpbnNpemUgJiBWb2x1bWUgTm9ybWFsaXplZCBcbiBQYXJ0aWNsZXMgKCMvTC9tbSkiLCB4ID0gIlNpemUgKG1tKSIpCgpFZ05QIDwtIGVnX2RhdGFibG9jayAlPiUKICBnZ3Bsb3QoYWVzKHggPSBsYiwgeSA9IG5wYXJ0aWNsZXMpKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX3lfbG9nMTAoKSArIAogIGdlb21fcGF0aChkYXRhID0gZWdfZGYpICsgbGFicyh5ID0gIk5vcm1hbGl6ZWQgUGFydGljbGVzIiAsIHggPSAiU2l6ZSAobW0pIikKCkVnVFAgPC0gZWdfZGF0YWJsb2NrICU+JQogIGdncGxvdChhZXMoeCA9IGxiLCB5ID0gVG90YWxQYXJ0aWNsZXMpKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX3lfbG9nMTAoKSArIAogIGdlb21fcGF0aChkYXRhID0gZWdfZGYpICsgbGFicyggeSA9ICJUb3RhbCBQYXJ0aWNsZXMgT2JzZXJ2ZWQgKCMpIiwgeCA9ICJTaXplIChtbSkiKQoKcGxvdF9ncmlkKEVnTk5QLCBFZ1RQLCBsYWJlbHMgPSBjKCJBIiwgIkIiKSkKZ2dzYXZlKCJmaWd1cmVzL0V4YW1wbGVQU0QxNjNtLnBuZyIpCmdnc2F2ZSgiZmlndXJlcy9FeGFtcGxlUFNEMTYzbS5zdmciKQoKYGBgCgojIFNtb290aCBmbHV4IGFuZCB1bSBkaXNhZ2dyZWdhdGlvbi4KCmBgYHtyfQpiZHMgJT4lIAogIGdncGxvdChhZXMoeSA9IGRlcHRoLCB4ID0gRmx1eF9TbW9vdGgsIGNvbCA9IGZhY3Rvcih0aW1lKSkpICsgZmFjZXRfd3JhcCh+cHJvamVjdCkgKyBnZW9tX3BvaW50KCkgKyBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKyBzY2FsZV94X2xvZzEwKCkKYGBgCgoKCgpgYGB7cn0KYmRzQWRkVGltZSA8LSBiZHMgJT4lCiAgbXV0YXRlKEhvdXIgPSBob3VyKHRpbWUpLCBEYXkgPSBkYXkodGltZSkpCgpGU0cxIDwtIGdhbShGbHV4X1Ntb290aH4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSArIHMoSG91ciwgayA9IDQsIGJzID0gImNjIiksIGtub3RzID0gbGlzdChIb3VyID0gYygwLCAyNCkpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHMiA8LSBnYW0oRmx1eF9TbW9vdGggfiBzKGRlcHRoLCBrID0gMykgKyBzKERheSwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHMyA8LSBnYW0oRmx1eF9TbW9vdGggfiBzKGRlcHRoLCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpzdW1tYXJ5KEZTRzEpCnN1bW1hcnkoRlNHMikKc3VtbWFyeShGU0czKQoKc3VtbWFyeShGU0cxKSRyLnNxIC0gc3VtbWFyeShGU0cyKSRyLnNxCnN1bW1hcnkoRlNHMikkci5zcSAtIHN1bW1hcnkoRlNHMykkci5zcQpzdW1tYXJ5KEZTRzMpJHIuc3EKYGBgCgpgYGB7cn0KYmRzICU+JSBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIpICU+JSBzZWxlY3QocHJvZmlsZSwgZGVwdGgsIEZsdXhfU21vb3RoKSAlPiUgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHByb2ZpbGUsIHZhbHVlc19mcm9tID0gRmx1eF9TbW9vdGgpCmBgYAoKU29tZXRoaW5nIGlzIG9mZi4gQWxsIG9mIHRoZSBmbHV4IHByb2ZpbGVzIGFyZSBpZGVudGljYWwuClNraXAgdGhpcwpgYGB7cn0KY2IxMCA8LSBjKCcjYTZjZWUzJywnIzFmNzhiNCcsJyNiMmRmOGEnLCcjMzNhMDJjJywnI2ZiOWE5OScsJyNlMzFhMWMnLCcjZmRiZjZmJywnI2ZmN2YwMCcsJyNjYWIyZDYnLCcjNmEzZDlhJykKcGx0MSA8LSBiZHMgJT4lICNmaWx0ZXIoREZQID4gMSkgJT4lICNmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBERlAsIGNvbCA9IGZhY3Rvcih0aW1lKSwgc2hhcGUgPSBmYWN0b3IodGltZSkpKSArIGZhY2V0X3dyYXAofnByb2plY3QpICsgZ2VvbV9wb2ludCgpICsgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpICsgeGxpbShjKDAuNSwgMS41KSkrIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEpICsKICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMocmVwKCJibGFjayIsIDUpLCByZXAoImJsdWUiLCA1KSkpICsgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IHJlcCgxOjUsIDIpKQoKcGxvdGx5OjpnZ3Bsb3RseShwbHQxKQpgYGAKCldoYXQgdGhlIGhlY2sgaXMgZ29pbmcgb24gd2l0aCBERlAgaGVyZS4gV2h5IGlzIGl0IHVzdWFsbHkgPiAxIHNob3VsZG4ndCBpdCBiZSBsZXNzIHRoYW4gMSB3aGVuIGZsdXggaXMgZGVjcmVhc2luZz8KVGhpcyB2ZXJ5IGRlZXAgaW5jcmVhc2luZyBmbHV4IHNlZW1zIGltcHJvYmFibGUgdG8gbWUuCkxldHMgY2hlY2sgdGhlIHNtb290aHMuIE9yIG9ubHkgZ28gdG8gMTAwMG0uCgosIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoKQpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQpzY2llbnRpZmljXzEwIDwtIGZ1bmN0aW9uKHgpIHtwYXJzZSh0ZXh0PWdzdWIoImVcXCsqIiwgIiAlKiUgMTBeIiwgc2NhbGVzOjpzY2llbnRpZmljX2Zvcm1hdCgpKHgpKSkgfQojaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTA3NjIyODcvaG93LWNhbi1pLWZvcm1hdC1heGlzLWxhYmVscy13aXRoLWV4cG9uZW50cy13aXRoLWdncGxvdDItYW5kLXNjYWxlcwojamFjb2JfbWFnbml0dWRlIDwtIGZ1bmN0aW9uKHgpe2V4cHJlc3Npb24oMTBecm91bmQobG9nMTAoeCkpKX0KCmNiMTAgPC0gYygnI2E2Y2VlMycsJyMxZjc4YjQnLCcjYjJkZjhhJywnIzMzYTAyYycsJyNmYjlhOTknLCcjZTMxYTFjJywnI2ZkYmY2ZicsJyNmZjdmMDAnLCcjY2FiMmQ2JywnIzZhM2Q5YScpCnBsdEZseCA8LSBiZHMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJFVE5QIikgJT4lICNmaWx0ZXIoREZQID4gMSkgJT4lICNmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBGbHV4X1Ntb290aCwgc2hhcGUgPSBmYWN0b3IoZGF5KHRpbWUpKSwgZmlsbCA9IGhvdXIodGltZSksIGdyb3VwID0gZmFjdG9yKHRpbWUpKSkgICsgZ2VvbV9wb2ludChzaXplID0gMywgc3Ryb2tlID0gMSkrCiAgZ2VvbV9wYXRoKCkgKwogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSsKICBzY2FsZV94X2xvZzEwKGxhYmVsID0gc2NpZW50aWZpY18xMCkgKwogICBzY2FsZV9jb2xvcl9ncmFkaWVudDIobG93ID0gImRhcmtncmVlbiIsIG1pZCA9ICJncmF5ODAiLCBoaWdoID0gInB1cnBsZSIsIG1pZHBvaW50ID0gMTApICsgc2NhbGVfc2hhcGVfbWFudWFsKG5hbWUgPSAiRGF5IG9mIE1vbnRoIiwgdmFsdWVzID0gcmVwKDIxOjI1LCAyKSkgKyAKICBzY2FsZV9maWxsX2dyYWRpZW50bihuYW1lID0gIkhvdXIgb2YgRGF5IiwgYnJlYWtzID0gYygwLCA2LCAxMiwgMTgsIDI0KSwgY29sb3JzID0gYygiYmxhY2siLCAiYmx1ZSIsICJ3aGl0ZSIsICJvcmFuZ2UiLCAiYmxhY2siKSkgKwogIApsYWJzKHggPSBicXVvdGUoU21vb3RoZWR+Rmx1eH4owrVtb2x+Qy9tXjIvZCkpLCB5ID0gIkRlcHRoIChtKSIpICsKICBnZW9tX3JlY3QoZGF0YSA9IGRhdGEuZnJhbWUocHJvamVjdCA9ICJFVE5QIiksIGFlcyh4bWluID0gMjAsIHhtYXggPSAxODAsIHltaW4gPSA3NSwgeW1heCA9IDUwMCksIGNvbG91ciA9ICJyZWQiLCBmaWxsID0gTkEsIGluaGVyaXQuYWVzID0gRkFMU0UpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IC4zKSwgbGVnZW5kLnNwYWNpbmcgPSB1bml0KC4xLCAiY20iKSkKCgoKcGx0Rmx4Tm9MZWdlbmQgPC0gcGx0Rmx4ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpwbHRGbHhMZWdlbmQgPC0gZ2V0X2xlZ2VuZChwbHRGbHgpCgpwbHRGbHgKI3Bsb3RseTo6Z2dwbG90bHkocGx0MSkKYGBgCgpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQpjYjEwIDwtIGMoJyNhNmNlZTMnLCcjMWY3OGI0JywnI2IyZGY4YScsJyMzM2EwMmMnLCcjZmI5YTk5JywnI2UzMWExYycsJyNmZGJmNmYnLCcjZmY3ZjAwJywnI2NhYjJkNicsJyM2YTNkOWEnKQpwbHRGbHhab29tIDwtIGJkcyAlPiUgZmlsdGVyKHByb2plY3QgPT0gIkVUTlAiICYgZGVwdGggPD0gNTAwICYgZGVwdGggPj0gNzUpICU+JSAjZmlsdGVyKHByb2ZpbGUgJWluJSBjKCJzdG5fMDQzIiwgInAxNm5fMTAwIikpICU+JQogIGdncGxvdChhZXMoeSA9IGRlcHRoLCB4ID0gRmx1eF9TbW9vdGgsIHNoYXBlID0gZmFjdG9yKGRheSh0aW1lKSksIGZpbGwgPSBob3VyKHRpbWUpLCBncm91cCA9IGZhY3Rvcih0aW1lKSkpICsgZ2VvbV9wb2ludChzaXplID0gMywgc3Ryb2tlID0gMSkrCiAgZ2VvbV9wYXRoKCkgKwogIHNjYWxlX3lfcmV2ZXJzZSgpKwogICNzY2FsZV94X2xvZzEwKCkgKwogIHNjYWxlX3hfbG9nMTAoYnJlYWtzID0gYyhzZXEoZnJvbSA9IDIwLCB0byA9IDUwLCBieSA9IDEwKSwgc2VxKGZyb20gPSA2MCwgdG8gPSAxODAsIGJ5ID0gMjApKSwgbGltaXRzID0gYygyMCwgMTgwKSkgKwogICBzY2FsZV9jb2xvcl9ncmFkaWVudDIobG93ID0gImRhcmtncmVlbiIsIG1pZCA9ICJncmF5ODAiLCBoaWdoID0gInB1cnBsZSIsIG1pZHBvaW50ID0gMTApICsgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IHJlcCgyMToyNSwgMikpICsgCiAgc2NhbGVfZmlsbF9ncmFkaWVudG4oYnJlYWtzID0gYygwLCA2LCAxMiwgMTgsIDI0KSwgY29sb3JzID0gYygiYmxhY2siLCAiYmx1ZSIsICJ3aGl0ZSIsICJvcmFuZ2UiLCAiYmxhY2siKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArCmxhYnMoeCA9ICJTbW9vdGhlZCBGbHV4IiwgeSA9ICJEZXB0aCIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKcGx0Rmx4Wm9vbQojcGxvdGx5OjpnZ3Bsb3RseShwbHQxKQpgYGAKCgoKYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0KY2IxMCA8LSBjKCcjYTZjZWUzJywnIzFmNzhiNCcsJyNiMmRmOGEnLCcjMzNhMDJjJywnI2ZiOWE5OScsJyNlMzFhMWMnLCcjZmRiZjZmJywnI2ZmN2YwMCcsJyNjYWIyZDYnLCcjNmEzZDlhJykKcGx0RGVsdGEzIDwtIGJkcyAlPiUgZmlsdGVyKHByb2plY3QgPT0gIkVUTlAiKSAlPiUgI2ZpbHRlcihERlAgPiAxKSAlPiUgI2ZpbHRlcihwcm9maWxlICVpbiUgYygic3RuXzA0MyIsICJwMTZuXzEwMCIpKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCwgeCA9IHByYWNtYTo6bnRocm9vdChERi9EWiwgNSksIHNoYXBlID0gZmFjdG9yKGRheSh0aW1lKSksIGZpbGwgPSBob3VyKHRpbWUpLCBncm91cCA9IGZhY3Rvcih0aW1lKSkpICArIGdlb21fcG9pbnQoc2l6ZSA9IDMsIHN0cm9rZSA9IDEpKwogIGdlb21fcGF0aCgpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkrCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTIuMSwgLjYpLCBicmVha3MgPSBzZXEoZnJvbSA9IC0yLCB0byA9IC43NSwgYnkgPSAwLjUpKSArCiAgI3NjYWxlX3hfbG9nMTAoKSArCiAgIHNjYWxlX2NvbG9yX2dyYWRpZW50Mihsb3cgPSAiZGFya2dyZWVuIiwgbWlkID0gImdyYXk4MCIsIGhpZ2ggPSAicHVycGxlIiwgbWlkcG9pbnQgPSAxMCkgKyBzY2FsZV9zaGFwZV9tYW51YWwobmFtZSA9ICJEYXkgb2YgTW9udGgiLCB2YWx1ZXMgPSByZXAoMjE6MjUsIDIpKSArIAogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKG5hbWUgPSAiSG91ciIsIGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKSArCiAgbGFicyh4ID0gYnF1b3RlKChERi9EWileezEvNX1+KMK1bW9sQy9tXjMvZCleezEvNX0pLCB5ID0gIkRlcHRoIChtKSIpICsgdGhlbWUobGVnZW5kLnBvcyA9ICJub25lIikKICAjbGFicyh4ID0gIihERi9EWikgXiAxLzUgKMK1bW9sIEMvbV4zL2QpIF4gMS81IikKCnBsdERlbHRhMwojcGxvdGx5OjpnZ3Bsb3RseShwbHQxcG9zKQpgYGAKCgoKYGBge3IgZmlnLmhlaWdodD04LCBmaWcud2lkdGggPSA4fQojICNwbG90X2dyaWQocGx0Rmx4Tm9MZWdlbmQsIHBsdEZseFpvb20sIHBsdERlbHRhMywgcGx0Rmx4TGVnZW5kKQojIAojIHBsdEZseExlZ2VuZCA8LSBnZXRfbGVnZW5kKHBsdEZseCArIHRoZW1lKGxlZ2VuZC5ib3gubWFyZ2luID0gbWFyZ2luKDAsIDAsIDQwLCAxMCkpKQojIAojIHBnVG9wIDwtIHBsb3RfZ3JpZChwbHRGbHhOb0xlZ2VuZCwgcGx0Rmx4Wm9vbSArIHRoZW1lKHBsb3QubWFyZ2luID0gdW5pdChjKDEsIDAsIDMsIDApLCB1bml0cyA9ICJjbSIpKSwgcmVsX3dpZHRocyA9IGMoMiwgMSksIGxhYmVscyA9IGMoIkEiLCAiQiIpKQojIHBnQm90dG9tIDwtIHBsb3RfZ3JpZChwbHREZWx0YTMsIHBsdEZseExlZ2VuZCAsIHJlbF93aWR0aHMgPSBjKDMsIDEpLCBsYWJlbHMgPSBjKCJDIiwgIiIpLCBsYWJlbF9zaXplID0gMTQpCiMgcGdCb3RoIDwtIHBsb3RfZ3JpZChwZ1RvcCwgcGdCb3R0b20sIG5jb2wgPSAxKQojIAojIHBnQm90aAojIAojIGdnc2F2ZSgiZmlndXJlcy9GbHV4RGVlcERpdmUucG5nIikKIyBnZ3NhdmUoImZpZ3VyZXMvRmx1eERlZXBEaXZlLnN2ZyIpCgpgYGAKCgpXaXRoaW4gcGFuZWwgZHJhd2luZwoKCmBgYHtyIGZpZy5oZWlnaHQgPSA1LCBmaWcud2lkdGggPSA1fQpwZ1RvcCA8LSBnZ2RyYXcocGx0Rmx4Tm9MZWdlbmQgCiAgICAgICApICsKICBkcmF3X3Bsb3QocGx0Rmx4Wm9vbSwgLjQsIC4yNSwgLjU1LCAuNjApICsKICBkcmF3X3Bsb3RfbGFiZWwoCiAgICBjKCIiLCJCIiksCiAgICBjKC4wNSwgMC41NSksCiAgICBjKDEsIDAuODUpLAogICAgc2l6ZSA9IDE2CiAgKQpwZ1RvcApgYGAKcGdCb3R0b20gPC0gcGxvdF9ncmlkKHBsdERlbHRhMywgcGx0Rmx4TGVnZW5kICwgcmVsX3dpZHRocyA9IGMoMywgMSksIGxhYmVscyA9IGMoIkMiLCAiIiksIGxhYmVsX3NpemUgPSAxNCkKCgoKCkkgZG9uJ3Qga25vdyB3aGF0cyBnb2luZyBvbiBiZWxvdyBoZXJlCgpgYGB7ciBmaWcuaGVpZ2h0ID0gOSwgZmlnLndpZHRoID0gNX0KcGdCb3R0b20gPC0gcGx0RGVsdGEzICArIGdlb21fcmVjdChhZXMoeG1pbiA9IC0yLCB4bWF4ID0gLTEuMTUsIHltaW4gPSAxNzAsIHltYXggPSAxMDAwKSwgY29sb3VyID0gImdyYXk1MCIsIGZpbGwgPSBOQSwgaW5oZXJpdC5hZXMgPSBGQUxTRSkgKyBkcmF3X3Bsb3QocGx0Rmx4TGVnZW5kICwgLTEuOSwgLTU3NSwgLjcpCnBnQm90aCA8LSBwbG90X2dyaWQocGdUb3AgKyB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygwLCAwLCAwLCAwKSwgdW5pdHMgPSAiY20iKSksCiAgICAgICAgICAgICAgICAgICAgcGdCb3R0b20gKyB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygwLCAwLCAwLCAwKSwgdW5pdHMgPSAiY20iKSksCiAgICAgICAgICAgICAgICAgICAgbmNvbCA9IDEsIHJlbF9oZWlnaHRzID0gYyg0LCA0KSwgbGFiZWxzID0gYygiQSIsICJDIiksIGxhYmVsX3NpemUgPSAxNikKcGdCb3RoCgpnZ3NhdmUoImZpZ3VyZXMvRmx1eERlZXBEaXZlLnBuZyIpCmdnc2F2ZSgiZmlndXJlcy9GbHV4RGVlcERpdmUuc3ZnIikKYGBgCgoKCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoID0gOH0KIyAjcGxvdF9ncmlkKHBsdEZseE5vTGVnZW5kLCBwbHRGbHhab29tLCBwbHREZWx0YTMsIHBsdEZseExlZ2VuZCkKIyAKIyBwbHRGbHhMZWdlbmQgPC0gZ2V0X2xlZ2VuZChwbHRGbHggKyB0aGVtZShsZWdlbmQuYm94Lm1hcmdpbiA9IG1hcmdpbigwLCAwLCA0MCwgMTApKSkKIyAKIyBwZ1RvcCA8LSBwbG90X2dyaWQocGx0Rmx4Tm9MZWdlbmQgKyB5bGltKGMoMTAwMCwgMCkpLCBwbHRGbHhab29tICsgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMSwgMCwgMywgMCksIHVuaXRzID0gImNtIikpLCByZWxfd2lkdGhzID0gYygyLCAxKSwgbGFiZWxzID0gYygiQSIsICJCIikpCiMgcGdCb3R0b20gPC0gcGxvdF9ncmlkKHBsdERlbHRhMyArIHlsaW0oYygxMDAwLCAwKSksIHBsdEZseExlZ2VuZCAsIHJlbF93aWR0aHMgPSBjKDMsIDEpLCBsYWJlbHMgPSBjKCJDIiwgIiIpKQojIHBnQm90aCA8LSBwbG90X2dyaWQocGdUb3AsIHBnQm90dG9tLCBuY29sID0gMSkKIyAKIyBwZ0JvdGgKIyAKIyAjZ2dzYXZlKCJmaWd1cmVzL0ZsdXhTaGFsbG93RGl2ZS5wbmciKQojICNnZ3NhdmUoImZpZ3VyZXMvRmx1eFNoYWxsb3dEaXZlLnN2ZyIpCgpgYGAKClRlc3QgZm9yIGRheSB0byBkYXkgYW5kIGhvdXJseSB2YXJpYWJpbGl0eQpgYGB7cn0KYmRzQWRkVGltZSA8LSBiZHMgJT4lCiAgbXV0YXRlKEhvdXIgPSBob3VyKHRpbWUpLCBEYXkgPSBkYXkodGltZSkpCgpERkcxIDwtIGdhbShERi9EWn4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSArIHMoSG91ciwgayA9IDQsIGJzID0gImNjIiksIGtub3RzID0gbGlzdChIb3VyID0gYygwLCAyNCkpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKREZHMiA8LSBnYW0oREYvRFogfiBzKGRlcHRoLCBrID0gMykgKyBzKERheSwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKREZHMyA8LSBnYW0oREYvRFogfiBzKGRlcHRoLCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpzdW1tYXJ5KERGRzEpCnN1bW1hcnkoREZHMikKc3VtbWFyeShERkczKQoKc3VtbWFyeShERkcxKSRyLnNxIC0gc3VtbWFyeShERkcyKSRyLnNxCnN1bW1hcnkoREZHMikkci5zcSAtIHN1bW1hcnkoREZHMykkci5zcQpzdW1tYXJ5KERGRzMpJHIuc3EKYGBgCnBuZyhmaWxlbmFtZSA9ICIuL2ZpZ3VyZXMvQ29tYmluZWRQMkluZm8ucG5nIiwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gOCwgdW5pdHMgPSAiaW4iLCByZXMgPSAyMDApClN0YXRpb25JbmZvUGxvdCgpCmRldi5vZmYoKQpgYGB7ciBmaWcuaGVpZ2h0ID0gOCwgZmlnLndpZHRoID0gMTB9CiNwbG90Lm5ldygpCkZsdXhHYW1QbG90IDwtIGZ1bmN0aW9uKCl7CiAgcGFyKG1mcm93ID0gYygyLDIpKQogIHBsb3QoREZHMSkKICBtdGV4dChleHByZXNzaW9uKGJvbGQoIkMiKSksIHNpZGUgPSAzLCBsaW5lID0gMCwgYWRqID0gMCwgY2V4ID0gMikKICBwYXIobWZnID0gYygxLDEpKQogIG10ZXh0KGV4cHJlc3Npb24oYm9sZCgiQSIpKSwgc2lkZSA9IDMsIGxpbmUgPSAwLCBhZGogPSAwLCBjZXggPSAyKQogIHBhcihtZmcgPSBjKDEsMikpCiAgbXRleHQoZXhwcmVzc2lvbihib2xkKCJCIikpLCBzaWRlID0gMywgbGluZSA9IDAsIGFkaiA9IDAsIGNleCA9IDIpCn0KCkZsdXhHYW1QbG90KCkKCnBuZyhmaWxlbmFtZSA9ICIuL2ZpZ3VyZXMvRmx1eEdhbVBsb3QucG5nIiwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gOCwgdW5pdHMgPSAiaW4iLCByZXMgPSAyMDApCkZsdXhHYW1QbG90KCkKZGV2Lm9mZigpCmBgYAoKI09zcHMKCih1IG1vbCBDIC8gbV4zIC8gZGF5KQpgYGB7ciBmaWcud2lkdGggPSA2LCBmaWcuaGVpZ2h0ID0gNH0KYmRzICU+JSBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIpICU+JQogIGdncGxvdChhZXMoeSA9IGRlcHRoLCB4ID0gcHJhY21hOjpudGhyb290KG9zcHNEWiwgMyksIHNoYXBlID0gZmFjdG9yKGRheSh0aW1lKSksIGZpbGwgPSBob3VyKHRpbWUpLCBncm91cCA9IGZhY3Rvcih0aW1lKSkpICsgZ2VvbV9wb2ludChzaXplID0gMikgKyBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xLCAxKSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDApICsgICBzY2FsZV9zaGFwZV9tYW51YWwobmFtZSA9ICJEYXkgb2YgTW9udGgiLCB2YWx1ZXMgPSByZXAoMjE6MjUsIDIpKSArIGxhYnMoeCA9IGJxdW90ZSgiT2JzZXJ2ZWQgLSBNb2RlbGVkIFNtYWxsIFBhcnRpY2xlIEZsdXgifijOvG1vbC9tXjMvZGF5KSkpICsKICBzY2FsZV9maWxsX2dyYWRpZW50bihuYW1lID0gIkhvdXIgb2YgRGF5IiwgYnJlYWtzID0gYygwLCA2LCAxMiwgMTgsIDI0KSwgY29sb3JzID0gYygiYmxhY2siLCAiYmx1ZSIsICJ3aGl0ZSIsICJvcmFuZ2UiLCAiYmxhY2siKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNzUsIGNvbG9yID0gImRhcmtncmVlbiIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gOTUwLCBjb2xvciA9ICJkYXJrYmx1ZSIpCgojZ2dzYXZlKCIuLmZpZ3VyZXMvRmx1eFNpemVTaGlmdC5zdmciCgogZ2dzYXZlKCJmaWd1cmVzL0ZsdXhTaXplU2hpZnQucG5nIikKIGdnc2F2ZSgiZmlndXJlcy9GbHV4U2l6ZVNoaWZ0LnN2ZyIpCmBgYAoKYGBge3J9CmJkc0FkZFRpbWUgPC0gYmRzICU+JQogIG11dGF0ZShIb3VyID0gaG91cih0aW1lKSwgRGF5ID0gZGF5KHRpbWUpKQoKT1pHMSA8LSBnYW0ob3Nwc0RaIH4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSArIHMoSG91ciwgayA9IDQsIGJzID0gImNjIiksIGtub3RzID0gbGlzdChIb3VyID0gYygwLCAyNCkpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKT1pHMiA8LSBnYW0ob3Nwc0RaIH4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCk9aRzMgPC0gZ2FtKG9zcHNEWiB+IHMoZGVwdGgsIGsgPSAzKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCnN1bW1hcnkoT1pHMSkKc3VtbWFyeShPWkcyKQpzdW1tYXJ5KE9aRzMpCgpzdW1tYXJ5KE9aRzEpJHIuc3EgLSBzdW1tYXJ5KE9aRzIpJHIuc3EKc3VtbWFyeShPWkcyKSRyLnNxIC0gc3VtbWFyeShPWkczKSRyLnNxCnN1bW1hcnkoT1pHMykkci5zcQpgYGAKCmBgYHtyfQpPU01TR2FtUGxvdCA8LSBmdW5jdGlvbigpewogIHBhcihtZnJvdyA9IGMoMSwyKSkKICBwbG90KE9aRzIpCiAgbXRleHQoZXhwcmVzc2lvbihib2xkKCJCIikpLCBzaWRlID0gMywgbGluZSA9IDAsIGFkaiA9IDAsIGNleCA9IDIpCiAgcGFyKG1mZyA9IGMoMSwxKSkKICBtdGV4dChleHByZXNzaW9uKGJvbGQoIkEiKSksIHNpZGUgPSAzLCBsaW5lID0gMCwgYWRqID0gMCwgY2V4ID0gMikKfQoKT1NNU0dhbVBsb3QoKQoKcG5nKGZpbGVuYW1lID0gIi4vZmlndXJlcy9PU01TR2FtUGxvdC5wbmciLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2LCB1bml0cyA9ICJpbiIsIHJlcyA9IDIwMCkKT1NNU0dhbVBsb3QoKQoKZGV2Lm9mZigpCmBgYAoKYGBge3J9CnBsb3QoT1pHMikKYGBgCgoKYGBge3J9CmJkcyAlPiUgZmlsdGVyKHByb2plY3QgPT0gIlAxNiIpICU+JQogIGdncGxvdChhZXMoeSA9IGRlcHRoLCB4ID0gb3Nwc0RaKSkgKyBmYWNldF93cmFwKH5wcm9qZWN0KSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDUwMCwgMCkpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkKYGBgCgojIFRyYXAgZGF0YQpgYGB7cn0KdHJhcEZsdXgzIDwtIHJlYWRfY3N2KCJkYXRhT3V0L2ZsdXhNU19kaXN0aWxsZWQuY3N2IikKVVZQRmx1eENvbWIgPC0gcmVhZF9jc3YoImRhdGFPdXQvQ29tYmluZWRQcm9maWxlRmx1eEVzdF9EUy5jc3YiKQpVVlBGbHV4T0UgPC0gcmVhZF9jc3YoImRhdGFPdXQvT2JzZXJ2ZWRWc0V4cGVjdGVkRmx1eC5jc3YiKQoKYGBgCgpgYGB7cn0KdHJhcEZsdXgzCmBgYApgYGB7cn0KVVZQRmx1eENvbWIKYGBgCgoKYGBge3J9CgpmbHV4TVNfZGlzdGlsbGVkX3RvUGxvdCA8LSB0cmFwRmx1eDMgJT4lCiAgbXV0YXRlKFNhbXBsZVR5cGUgPSByZWNvZGUoU2FtcGxlVHlwZSwgYHBsdXMucGAgPSAicGx1cy1wYXJ0aWNsZXMiLCB0b3AgPSAidG9wLWNvbGxlY3RvciIpKQpgYGAKCmBgYHtyfQpVVlBGbHV4Q29tYiAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCkpICArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMjAwKSkgKwogIGdlb21fcG9pbnQoYWVzKHkgPSBEZXB0aCwgeCA9IENfZmx1eF91bW9sLCBmaWxsID0gU2FtcGxlVHlwZSwgc2hhcGUgPSBUcmFwVHlwZSksCiAgICAgICAgICAgICBjb2xvdXIgPSAiYmxhY2siLCBzdHJva2UgPSAxLCBzaXplID0gNSwgZGF0YSA9IGZsdXhNU19kaXN0aWxsZWRfdG9QbG90KSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IEZsdXgpLCBzaXplID0gMywgc2hhcGUgPSAyMSwgY29sb3IgPSAid2hpdGUiLCBmaWxsID0gImJsYWNrIikgKwogIGdlb21fcG9pbnQoYWVzKHggPSAtMSwgeSA9IC0xLCBzaXplID0gIlVWUCIpKSArICMgZHVtbXkgcG9pbnQgZm9yIHRoZSBsZWdlbmQKc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMjUsIDIyKSkrCiAgc2NhbGVfc2l6ZV9tYW51YWwodmFsdWVzID0gMSwgbmFtZSA9ICIiKSArCiAgeWxhYigiRGVwdGggKG0pIikgKyB4bGFiKCJGbHV4IMK1bW9sQy9tXjIvZGF5IikgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2hhcGUgPSAyMSkpKSArCiAgdGhlbWVfY293cGxvdCgpICsgCiAgdGhlbWUoCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gYygwLjUsIDAuNCksCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSksCiAgICAgICAgbGVnZW5kLm1hcmdpbiA9IG1hcmdpbigtMTAsIDUsIDEwLCA1KQogICkgKwogIGdlb21fcmVjdChkYXRhID0gZGF0YS5mcmFtZShwcm9qZWN0ID0gIkVUTlAiKSwgYWVzKHhtaW4gPSAxNSwgeG1heCA9IDMyLCB5bWluID0gNDUsIHltYXggPSAxOTUpLCBjb2xvdXIgPSAicmVkIiwgZmlsbCA9IE5BLCBpbmhlcml0LmFlcyA9IEZBTFNFKQojIGdnc2F2ZSgiZmlndXJlcy9GaXR0ZWRGbHV4LnBuZyIpCiMgZ2dzYXZlKCJmaWd1cmVzL0ZpdHRlZEZsdXguc3ZnIikKYGBgCgpgYGB7cn0KVVZQRmx1eENvbWIgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgpKSAgKyBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDIwMCkpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gRGVwdGgsIHggPSBDX2ZsdXhfdW1vbCwgZmlsbCA9IFNhbXBsZVR5cGUsIHNoYXBlID0gVHJhcFR5cGUpLAogICAgICAgICAgICAgY29sb3VyID0gImJsYWNrIiwgc3Ryb2tlID0gMSwgc2l6ZSA9IDUsIGRhdGEgPSBmbHV4TVNfZGlzdGlsbGVkX3RvUGxvdCkgKwogIGdlb21fbGluZShhZXMoeCA9IEZsdXgpLCBzaXplID0gMSwgY29sb3IgPSAiYmxhY2siKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IC0xLCB5ID0gLTEsIHNpemUgPSAiVVZQIEVzdGltYXRlIikpICsgIyBkdW1teSBwb2ludCBmb3IgdGhlIGxlZ2VuZAogIGdlb21fcG9pbnQoYWVzKHggPSB0b3RfZmx1eDIpLCBzaXplID0gMywgc2hhcGUgPSAyMSwgY29sb3IgPSAid2hpdGUiLCBmaWxsID0gImJsYWNrIiwgZGF0YSA9IFVWUEZsdXhPRSkgKwpzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygyNSwgMjIpKSsKICBzY2FsZV9zaXplX21hbnVhbCh2YWx1ZXMgPSAxLCBuYW1lID0gIiIpICsKICB5bGFiKCJEZXB0aCAobSkiKSArIHhsYWIoIkZsdXggwrVtb2xDL21eMi9kYXkiKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaGFwZSA9IDIxKSkpICsKICB0aGVtZV9jb3dwbG90KCkgKyAKICB0aGVtZSgKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSBjKDAuNSwgMC40KSwKICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSwKICAgICAgICBsZWdlbmQubWFyZ2luID0gbWFyZ2luKC0xMCwgNSwgMTAsIDUpCiAgKSArCiAgZ2VvbV9yZWN0KGRhdGEgPSBkYXRhLmZyYW1lKHByb2plY3QgPSAiRVROUCIpLCBhZXMoeG1pbiA9IDE1LCB4bWF4ID0gMzIsIHltaW4gPSA0NSwgeW1heCA9IDE5NSksIGNvbG91ciA9ICJyZWQiLCBmaWxsID0gTkEsIGluaGVyaXQuYWVzID0gRkFMU0UpCmdnc2F2ZSgiZmlndXJlcy9GaXR0ZWRGbHV4LnBuZyIpCmdnc2F2ZSgiZmlndXJlcy9GaXR0ZWRGbHV4LnN2ZyIpCmBgYAoKIyMgRXhhbXBsZSBwYXJ0aWNsZSBzaXplIGRpc3RyaWJ1dGlvbgoKaG9yaXpvbnRhbEdhbVBsb3QgPC0gZGF0YUdhbUhvcml6b250YWwgJT4lIGdncGxvdChhZXMoeCA9IHJlc3BfZml0LCB5ID0gZGVwdGgsIGNvbCA9IGxvZyhsYiksIGdyb3VwID0gbGIpKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgZ2VvbV9wb2ludCgpICsgc2NhbGVfeF9sb2cxMChsaW1pdHMgPSBjKDEwXi04LCBOQSkpICsgc2NhbGVfY29sb3JfdmlyaWRpc19jKCkgKyBnZW9tX3BhdGgoKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gNSkgICsgZ2VvbV9lcnJvcmJhcihhZXMoeG1pbiA9IHJlc3BfbG93ZXIsIHhtYXggPSByZXNwX3VwcGVyKSwgd2lkdGggPSAxMCwgYWxwaGEgPSAwLjUpKyB0aGVtZV9idygpCgpgYGB7ciBmaWcud2lkdGg9IDEwfQpUUFBsb3QgPC0gYmVzICU+JSBmaWx0ZXIocHJvZmlsZSA9PSAic3RuXzA0MyIpICU+JSBncm91cF9ieShsYikgJT4lIGdncGxvdChhZXMoeCA9IFRvdGFsUGFydGljbGVzLCB5ID0gZGVwdGgsIGNvbCA9IGxvZyhsYiksIGdyb3VwID0gbGIpKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX2NvbG9yX3ZpcmlkaXNfYygpICsgZ2VvbV9wYXRoKCkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDUpICsgbGFicyh5ID0gIkRlcHRoIChtKSIsIHggPSAiVG90YWxQYXJ0aWNsZXMgT2JzZXJ2ZWQgKCMpIikKCm5ucFBsb3QgPC0gYmVzICU+JSBmaWx0ZXIocHJvZmlsZSA9PSAic3RuXzA0MyIpICU+JSBncm91cF9ieShsYikgJT4lIGdncGxvdChhZXMoeCA9IG5fbnBhcnRpY2xlcywgeSA9IGRlcHRoLCBjb2wgPSBsb2cobGIpLCBncm91cCA9IGxiKSkgKyBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKyBnZW9tX3BvaW50KCkgKyBzY2FsZV94X2xvZzEwKCkgKyBzY2FsZV9jb2xvcl92aXJpZGlzX2MoKSArIGdlb21fcGF0aCgpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSA1KSArIGxhYnMoeSA9ICJEZXB0aCAobSkiLCB4ID0gIkJpbnNpemUgYW5kIFZvbHVtZSBOb3JtYWxpemVkIFBhcnRpY2xlcyAoIy9ML21tKSIpCgpGaXRQbG90IDwtIGJlcyAlPiUgZmlsdGVyKHByb2ZpbGUgPT0gInN0bl8wNDMiKSAlPiUgZ3JvdXBfYnkobGIpICU+JSBnZ3Bsb3QoYWVzKHggPSBubnBfc21vb3RoLCB4bWluID0gbm5wX2xvd2VyLCB4bWF4ID0gbm5wX3VwcGVyLCB5ID0gZGVwdGgsIGNvbCA9IGxvZyhsYiksIGdyb3VwID0gbGIpKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX2NvbG9yX3ZpcmlkaXNfYygpICsgZ2VvbV9wYXRoKCkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDUpICsgbGFicyh5ID0gIkRlcHRoIChtKSIsIHggPSAiU21vb3RoZWQgLSBOb3JtYWxpemVkIFBhcnRpY2xlcyAoIy9ML21tKSIpICsgZ2VvbV9lcnJvcmJhcih3aWR0aCA9IDEwLCBhbHBoYSA9IDAuNSkKCm5wTGVnZW5kIDwtIGdldF9sZWdlbmQoRml0UGxvdCArIHRoZW1lKGxlZ2VuZC5ib3gubWFyZ2luID0gbWFyZ2luKDAsIDAsIDQwLCAyMDApKSArIGxhYnMoY29sID0gZXhwcmVzc2lvbihsb2dbZV0oU2l6ZSAobW0pKSkpKQoKcGxvdF9ncmlkKAogIFRQUGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksCiAgbm5wUGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksCiAgbnBMZWdlbmQgLAogIEZpdFBsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCikKCmdnc2F2ZSgiZmlndXJlcy9BbGxQYXJ0aWNsZVNpemVzLnN2ZyIpCmBgYAoKCiMjIFdlYmVyIEJpYW5jaGkgRmlncwoKCgoKYGBge3J9ClNhbWVHYW0gPC0gZ2FtKFRvdGFsUGFydGljbGVzIH5zKGxvZyhsYiksIGxvZyhkZXB0aCksIGJ5ID0gZmFjdG9yKHRpbWUpKSwgb2Zmc2V0ID0gbG9nKHZvbCAqIGJpbnNpemUpLCBmYW1pbHkgPSBuYigpLAogICAgZGF0YSA9IGJlcyAlPiUgZmlsdGVyKHByb2plY3QgPT0gIkVUTlAiKSkKYGBgCgpgYGB7cn0KYmVzRSA8LSBiZXMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJFVE5QIikKCmxiX25ldyA8LSBleHAoc2VxKGZyb20gPSBsb2coMC4xKSwgdG8gPSBsb2coMi4xKSwgYnkgPSAwLjA1KSkKdWJfbmV3IDwtIGxlYWQobGJfbmV3KQpiaW5zaXplX25ldyA8LSB1Yl9uZXcgLSBsYl9uZXcKCmxiYnMgPC0gdGliYmxlKGxiID0gbGJfbmV3LCB1YiA9IHViX25ldywgYmluc2l6ZSA9IGJpbnNpemVfbmV3KQoKRXhwYW5kZWQgPC0gZXhwYW5kX2dyaWQobGIgPSBleHAoc2VxKGZyb20gPSBsb2coMC4xKSwgdG8gPSBsb2coMiksIGJ5ID0gMC4wNSkpLCBkZXB0aCA9IHNlcShmcm9tID0gMjAsIHRvID0gMjAwMCwgYnkgPSAyMCksIHRpbWUgPSBhcy5mYWN0b3IodW5pcXVlKGJlc0UkdGltZSkpKSAlPiUgbGVmdF9qb2luKGxiYnMsIGJ5ID0gImxiIikKClByZWQgPC0gZXhwKHByZWRpY3QoU2FtZUdhbSwgRXhwYW5kZWQpKQpUb1Bsb3QgPC0gYmluZF9jb2xzKEV4cGFuZGVkLCBubnBhcnRpY2xlcyA9IFByZWQpICU+JSBtdXRhdGUodGltZSA9IGFzLmNoYXJhY3Rlcih0aW1lKSkgJT4lIG11dGF0ZShucGFydGljbGVzID0gbm5wYXJ0aWNsZXMgKiBiaW5zaXplKQpgYGAKCmBgYHtyfQpUb1Bsb3QgJT4lIGZpbHRlcihsYiA8PSAyKSAlPiUgIGdncGxvdChhZXMoeCA9IGxiLCB5ID0gZGVwdGgsIGZpbGwgPSBsb2cxMChubnBhcnRpY2xlcyksIHogPSBsb2cxMChubnBhcnRpY2xlcykpKSArIGdlb21fdGlsZSgpICsgc2NhbGVfZmlsbF92aXJpZGlzX2MoKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgc2NhbGVfeF9sb2cxMCgpICArIGZhY2V0X3dyYXAofnRpbWUpICsgZ2VvbV9jb250b3VyKGNvbG9yID0gImJsYWNrIikKYGBgCmBgYHtyfQptZWFuQmVzZSA8LSBUb1Bsb3QgJT4lIGZpbHRlcihsYiA8PSAyKSAlPiUgZ3JvdXBfYnkobGIsIGRlcHRoKSAlPiUgc3VtbWFyaXplKG5wYXJ0aWNsZXMgPSBtZWFuKG5wYXJ0aWNsZXMpLCBubnBhcnRpY2xlcyA9IG1lYW4obm5wYXJ0aWNsZXMpKQoKV0JDb2xvck1hcCA8LSBtZWFuQmVzZSU+JQogICBnZ3Bsb3QoYWVzKHggPSBsYiwgeSA9IGRlcHRoLCBmaWxsID0gbG9nMTAobm5wYXJ0aWNsZXMpLCB6ID0gbG9nMTAobm5wYXJ0aWNsZXMpKSkgKyBnZW9tX3RpbGUoKSArIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG5hbWUgPSAibG9nMTAobnVtYmVyIGRlbnNpdHkgXG4gKG5vcm1hbGl6ZWQpKSIpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV94X2xvZzEwKCkgKyBnZW9tX2NvbnRvdXIoY29sb3IgPSAiYmxhY2siKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE2MCwgY29sb3IgPSAiZGFya2dyZWVuIikgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA4NTAsIGNvbG9yID0gImRhcmtibHVlIikKV0JDb2xvck1hcApgYGAKQXZlcmFnZSBvZiBldmVyeXRoaW5nCgpgYGB7cn0KbWVhbkJlc2UwNDMgPC0gVG9QbG90ICU+JSBmaWx0ZXIobGIgPD0gMiwgdGltZSA9PSAiMjAxNy0wMS0xMyAxMTo1MTozMSIpCgptZWFuQmVzZTA0MyU+JQogICBnZ3Bsb3QoYWVzKHggPSBsYiwgeSA9IGRlcHRoLCBmaWxsID0gbG9nMTAobm5wYXJ0aWNsZXMpLCB6ID0gbG9nMTAobm5wYXJ0aWNsZXMpKSkgKyBnZW9tX3RpbGUoKSArIHNjYWxlX2ZpbGxfdmlyaWRpc19jKCkgKyBzY2FsZV95X3JldmVyc2UoKSArIHNjYWxlX3hfbG9nMTAoKSArIGdlb21fY29udG91cihjb2xvciA9ICJibGFjayIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTYwLCBjb2xvciA9ICJkYXJrZ3JlZW4iKQpgYGAKSnVzdCAwNDMKCmBgYHtyfQptYkdhbSA8LSBtZWFuQmVzZSAlPiUgZ3JvdXBfYnkoZGVwdGgpICAlPiUgbmVzdCgpICU+JQogIG11dGF0ZShtb2QgPSBtYXAoZGF0YSwgfmdhbShsb2cobm5wYXJ0aWNsZXMpIH4gbG9nKGxiKSwgZmFtaWx5ID0gZ2F1c3NpYW4oKSwgZGF0YSA9IC4pKSkgJT4lIAogIG11dGF0ZShwc2QgPSBtYXBfZGJsKG1vZCwgfnN1bW1hcnkoLikkcC5jb2VmZlsyXSkpCmBgYAoKYGBge3J9Cm1iR2FtICU+JSBnZ3Bsb3QoYWVzKHggPSBwc2QsIHkgPSBkZXB0aCkpICsgZ2VvbV9wYXRoKCkgKyBzY2FsZV95X3JldmVyc2UoKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE2MCwgY29sb3IgPSAiZGFya2dyZWVuIikgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAgODUwLCBjb2xvciA9ICJkYXJrYmx1ZSIpCmBgYAoKYGBge3J9Cm1iR2FtIDwtIG1lYW5CZXNlMDQzICU+JSBncm91cF9ieShkZXB0aCkgICU+JSBuZXN0KCkgJT4lCiAgbXV0YXRlKG1vZCA9IG1hcChkYXRhLCB+Z2FtKGxvZyhubnBhcnRpY2xlcykgfiBsb2cobGIpLCBmYW1pbHkgPSBnYXVzc2lhbigpLCBkYXRhID0gLikpKSAlPiUgCiAgbXV0YXRlKHBzZCA9IG1hcF9kYmwobW9kLCB+c3VtbWFyeSguKSRwLmNvZWZmWzJdKSkKYGBgCgpgYGB7cn0KcFdCUFNEIDwtIG1iR2FtICU+JSBnZ3Bsb3QoYWVzKHggPSBwc2QsIHkgPSBkZXB0aCkpICsgZ2VvbV9wYXRoKCkgKyBzY2FsZV95X3JldmVyc2UoKSAgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNjAsIGNvbG9yID0gImRhcmtncmVlbiIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gIDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKQpwV0JQU0QKYGBgCgoKIyMgRmlnIDUgV0IKCmJkcyAlPiUgZmlsdGVyKHByb2ZpbGUgPT0gInN0bl8wNDMiLCBkZXB0aCA8PSAyMDAwKSAlPiUgZ2dwbG90KGFlcyh4ID0gcHNkX2dhbSwgeG1pbiA9IHBzZF9nYW0gLSBwc2Rfc2VnICogMiwgeG1heCA9IHBzZF9nYW0gKyBwc2Rfc2VnICogMiwgeSA9IGRlcHRoKSkgKyBnZW9tX3BhdGgoc2l6ZSA9IDEpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNzUsIGNvbG9yID0gImRhcmtncmVlbiIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gOTUwLCBjb2xvciA9ICJkYXJrYmx1ZSIpICsgZ2VvbV9yaWJib24oYWxwaGEgPSAwLjIpICsgbGFicyh4ID0gIlBTRCBzbG9wZSIpCgpBbGwgb2YgdGhlbQoKYGBge3J9CmJkcyAlPiUgZmlsdGVyKHByb2ZpbGUgPT0gInN0bl8wNDMiLCBkZXB0aCA8PSAyMDAwKSAlPiUgZ2dwbG90KGFlcyh4ID0gcHNkX2dhbSwgeG1pbiA9IHBzZF9nYW0gLSBwc2Rfc2VnICogMiwgeG1heCA9IHBzZF9nYW0gKyBwc2Rfc2VnICogMiwgeSA9IGRlcHRoKSkgKyBnZW9tX3BhdGgoc2l6ZSA9IDEpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNzUsIGNvbG9yID0gImRhcmtncmVlbiIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gOTUwLCBjb2xvciA9ICJkYXJrYmx1ZSIpICsgZ2VvbV9yaWJib24oYWxwaGEgPSAwLjIpICsgbGFicyh4ID0gIlBTRCBzbG9wZSIpCmBgYAowNDMgb25seQoKYGBge3J9CmJkcyAlPiUgZmlsdGVyKHByb2ZpbGUgPT0gInN0bl8wNDMiLCBkZXB0aCA8PSAyMDAwLCBkZXB0aCA+IDE3NSkgJT4lIGdncGxvdChhZXMoeCA9IHNtYWxsX2Jpb3ZvbHVtZSwgeSA9IGRlcHRoKSkgKyBnZW9tX3BhdGgoc2l6ZSA9IDEpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNzUsIGNvbG9yID0gImRhcmtncmVlbiIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gOTUwLCBjb2xvciA9ICJkYXJrYmx1ZSIpICsgZ2VvbV9wb2ludCgpCmBgYAoKYGBge3J9CnViRGYwIDwtIFRvUGxvdCAlPiUgbXV0YXRlKHViaW9tYXNzID0gbnBhcnRpY2xlcyAqIGxiIF4gYWdfZ2xvYmFsKQp1YkRmIDwtIHViRGYwICU+JSBncm91cF9ieSh0aW1lLCBkZXB0aCkgJT4lIHN1bW1hcml6ZSh1YmlvbWFzcyA9IHN1bSh1YmlvbWFzcykpICU+JSB1bmdyb3VwICU+JSBncm91cF9ieShkZXB0aCkKcGhvdGljQmlvbWFzcyA8LSB1YkRmICU+JSBmaWx0ZXIoZGVwdGggPD0gMTgwLCBkZXB0aCA+PSAxNjApICU+JSBzdW1tYXJpemUodWJpb21hc3MgPSBtZWFuKHViaW9tYXNzKSkgJT4lIHB1bGwodWJpb21hc3MpCnViRGYgPC0gdWJEZiAlPiUgbXV0YXRlKG5iaW9tYXNzID0gdWJpb21hc3MvcGhvdGljQmlvbWFzcykKdWJEZiAlPiUgZ2dwbG90KGFlcyh4ID0gbmJpb21hc3MsIHkgPSBkZXB0aCAsIGdyb3VwID0gdGltZSwgY29sID0gdGltZSkpICsgZ2VvbV9wYXRoKCkgKyBzY2FsZV95X3JldmVyc2UoKSArIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsMSkpCmBgYAoKCiAKYGBge3J9CnViRGYgPC0gVG9QbG90ICU+JSBtdXRhdGUodWJpb21hc3MgPSBucGFydGljbGVzICogbGIgXiBhZ19nbG9iYWwpICU+JSBncm91cF9ieSh0aW1lLCBkZXB0aCkgJT4lIHN1bW1hcml6ZSh1YmlvbWFzcyA9IHN1bSh1YmlvbWFzcykpICU+JSB1bmdyb3VwICU+JSBncm91cF9ieShkZXB0aCkgICU+JSBzdW1tYXJpc2UodWJpb21hc3MgPSBtZWFuKHViaW9tYXNzKSkKcGhvdGljQmlvbWFzcyA8LSB1YkRmICU+JSBmaWx0ZXIoZGVwdGggPD0gMTgwLCBkZXB0aCA+PSAxNjApICU+JSBzdW1tYXJpemUodWJpb21hc3MgPSBtZWFuKHViaW9tYXNzKSkgJT4lIHB1bGwodWJpb21hc3MpCnViRGYgPC0gdWJEZiAlPiUgbXV0YXRlKG5iaW9tYXNzID0gdWJpb21hc3MvcGhvdGljQmlvbWFzcykKdWJEZiAlPiUgZ2dwbG90KGFlcyh4ID0gbmJpb21hc3MsIHkgPSBkZXB0aCkpICsgZ2VvbV9wYXRoKCkgKyBzY2FsZV95X3JldmVyc2UoKSArIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsMSkpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKQpgYGAKCgojIyMgU21hbGwgcGFydGljbGVzIGJpb21hc3MKCmBgYHtyfQpQdWJEZiA8LSBUb1Bsb3QgJT4lIG11dGF0ZSh1YmlvbWFzcyA9IG5wYXJ0aWNsZXMgKiBsYiBeIGFnX2dsb2JhbCkgJT4lIGZpbHRlcihsYiA8IDAuNSkgJT4lIGdyb3VwX2J5KHRpbWUsIGRlcHRoKSAlPiUgc3VtbWFyaXplKHViaW9tYXNzID0gc3VtKHViaW9tYXNzKSkgJT4lIHVuZ3JvdXAgJT4lIGdyb3VwX2J5KGRlcHRoKSAgJT4lIHN1bW1hcmlzZSh1YmlvbWFzcyA9IG1lYW4odWJpb21hc3MpKQpwaG90aWNCaW9tYXNzIDwtIFB1YkRmICU+JSBmaWx0ZXIoZGVwdGggPD0gMTY1LCBkZXB0aCA+PSAxNTUpICU+JSBzdW1tYXJpemUodWJpb21hc3MgPSBtZWFuKHViaW9tYXNzKSkgJT4lIHB1bGwodWJpb21hc3MpClB1YkRmIDwtIFB1YkRmICU+JSBtdXRhdGUobmJpb21hc3MgPSB1YmlvbWFzcy9waG90aWNCaW9tYXNzKQpwV0JTIDwtIFB1YkRmICU+JSBnZ3Bsb3QoYWVzKHggPSBuYmlvbWFzcywgeSA9IGRlcHRoKSkgKyBnZW9tX3BhdGgoKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwxLjIpKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE2MCwgY29sb3IgPSAiZGFya2dyZWVuIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxLCBjb2xvciA9ICJncmF5NTAiKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGNvbG9yID0gImdyYXk1MCIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gODUwLCBjb2xvciA9ICJkYXJrYmx1ZSIpICsgbGFicyggeCA9ICJTbWFsbCBwYXJ0aWNsZSBtYXNzIChub3JtLikiKQpwV0JTCmBgYAoKYGBge3J9Ckx1YkRmIDwtIFRvUGxvdCAlPiUgbXV0YXRlKHViaW9tYXNzID0gbnBhcnRpY2xlcyAqIGxiIF4gYWdfZ2xvYmFsKSAlPiUgZmlsdGVyKGxiID49IDAuNSkgJT4lIGdyb3VwX2J5KHRpbWUsIGRlcHRoKSAlPiUgc3VtbWFyaXplKHViaW9tYXNzID0gc3VtKHViaW9tYXNzKSkgJT4lIHVuZ3JvdXAgJT4lIGdyb3VwX2J5KGRlcHRoKSAgJT4lIHN1bW1hcmlzZSh1YmlvbWFzcyA9IG1lYW4odWJpb21hc3MpKQpwaG90aWNCaW9tYXNzIDwtIEx1YkRmICU+JSBmaWx0ZXIoZGVwdGggPD0gMTY1LCBkZXB0aCA+PTE1NSkgJT4lIHN1bW1hcml6ZSh1YmlvbWFzcyA9IG1lYW4odWJpb21hc3MpKSAlPiUgcHVsbCh1YmlvbWFzcykKTHViRGYgPC0gTHViRGYgJT4lIG11dGF0ZShuYmlvbWFzcyA9IHViaW9tYXNzL3Bob3RpY0Jpb21hc3MpCnBXQkwgPC0gTHViRGYgJT4lIGdncGxvdChhZXMoeCA9IG5iaW9tYXNzLCB5ID0gZGVwdGgpKSArIGdlb21fcGF0aCgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDEpKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE2MCwgY29sb3IgPSAiZGFya2dyZWVuIikgKyBsYWJzKCB4ID0gIkxhcmdlIHBhcnRpY2xlIG1hc3MgKG5vcm0uKSIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwgY29sb3IgPSAiZ3JheTUwIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBjb2xvciA9ICJncmF5NTAiKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKQpwV0JMCmBgYAoKRm9yIHRvbSBhbmQgZGFuaWVsbGUKYGBge3J9CldCQ29sb3JNYXAKcFdCUFNECnBXQlMKcFdCTApgYGAKCmBgYHtyLCBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodD0zfQpXQkZpZzUgPC0gcGxvdF9ncmlkKHBXQlBTRCwgcFdCUyxwV0JMLCBucm93ID0gMSwgbGFiZWxzID0gYygiQiIsICJDIiwgIkQiKSkKV0JGaWc1CmBgYAoKYGBge3IgZmlnLmhlaWdodCA9IDYsIGZpZy53aWR0aCA9IDh9CldCY29tYmluZWQgPC0gcGxvdF9ncmlkKFdCQ29sb3JNYXAgKyB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygwLDMsMCwgMyksICJjbSIpKSwgV0JGaWc1LCBuY29sID0gMSwgbGFiZWxzID0gYygiQSIsICIiKSkKV0Jjb21iaW5lZAoKZ2dzYXZlKCJmaWd1cmVzL1dCTW9kZWxWYWxpZGF0aW9uLnBuZyIpCmBgYAoKIyMgUDE2IEZsdXggCgpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQpzY2llbnRpZmljXzEwIDwtIGZ1bmN0aW9uKHgpIHtwYXJzZSh0ZXh0PWdzdWIoImVcXCsqIiwgIiAlKiUgMTBeIiwgc2NhbGVzOjpzY2llbnRpZmljX2Zvcm1hdCgpKHgpKSkgfQojaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTA3NjIyODcvaG93LWNhbi1pLWZvcm1hdC1heGlzLWxhYmVscy13aXRoLWV4cG9uZW50cy13aXRoLWdncGxvdDItYW5kLXNjYWxlcwojamFjb2JfbWFnbml0dWRlIDwtIGZ1bmN0aW9uKHgpe2V4cHJlc3Npb24oMTBecm91bmQobG9nMTAoeCkpKX0KCmNiMTAgPC0gYygnI2E2Y2VlMycsJyMxZjc4YjQnLCcjYjJkZjhhJywnIzMzYTAyYycsJyNmYjlhOTknLCcjZTMxYTFjJywnI2ZkYmY2ZicsJyNmZjdmMDAnLCcjY2FiMmQ2JywnIzZhM2Q5YScpCnBsdEZseFAxNiA8LSBiZHMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJQMTYiKSAlPiUgI2ZpbHRlcihERlAgPiAxKSAlPiUgI2ZpbHRlcihwcm9maWxlICVpbiUgYygic3RuXzA0MyIsICJwMTZuXzEwMCIpKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCwgeCA9IEZsdXhfU21vb3RoLCBncm91cCA9IGZhY3Rvcih0aW1lKSkpICArIGdlb21fcG9pbnQoc2l6ZSA9IDMsIHN0cm9rZSA9IDEpKwogIGdlb21fcGF0aCgpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkrCiAgc2NhbGVfeF9sb2cxMChsaW1pdHMgPSBjKDM1LCAxNTApLGJyZWFrcyA9IHNlcShmcm9tID0gMjAsIHRvID0gMTUwLCBieSA9IDIwKSkgKwogICBzY2FsZV9jb2xvcl9ncmFkaWVudDIobG93ID0gImRhcmtncmVlbiIsIG1pZCA9ICJncmF5ODAiLCBoaWdoID0gInB1cnBsZSIsIG1pZHBvaW50ID0gMTApICsgc2NhbGVfc2hhcGVfbWFudWFsKG5hbWUgPSAiRGF5IG9mIE1vbnRoIiwgdmFsdWVzID0gcmVwKDIxOjI1LCAyKSkgKyAKICBzY2FsZV9maWxsX2dyYWRpZW50bihuYW1lID0gIkhvdXIgb2YgRGF5IiwgYnJlYWtzID0gYygwLCA2LCAxMiwgMTgsIDI0KSwgY29sb3JzID0gYygiYmxhY2siLCAiYmx1ZSIsICJ3aGl0ZSIsICJvcmFuZ2UiLCAiYmxhY2siKSkgKwogIApsYWJzKHggPSBicXVvdGUoU21vb3RoZWR+Rmx1eH4owrVtb2x+Qy9tXjIvZCkpLCB5ID0gIkRlcHRoIChtKSIpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAyMDAsIGNvbG9yID0gImRhcmtncmVlbiIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IC4zKSwgbGVnZW5kLnNwYWNpbmcgPSB1bml0KC4xLCAiY20iKSkKIyAKIyAKIyAKIyBwbHRGbHhOb0xlZ2VuZCA8LSBwbHRGbHggKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCiMgcGx0Rmx4TGVnZW5kIDwtIGdldF9sZWdlbmQocGx0Rmx4KQojIApwbHRGbHhQMTYKIyAjcGxvdGx5OjpnZ3Bsb3RseShwbHQxKQpgYGAKCmBgYHtyIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9CmNiMTAgPC0gYygnI2E2Y2VlMycsJyMxZjc4YjQnLCcjYjJkZjhhJywnIzMzYTAyYycsJyNmYjlhOTknLCcjZTMxYTFjJywnI2ZkYmY2ZicsJyNmZjdmMDAnLCcjY2FiMmQ2JywnIzZhM2Q5YScpCnBsdERlbHRhM1AxNiA8LSBiZHMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJQMTYiKSAlPiUgI2ZpbHRlcihERlAgPiAxKSAlPiUgI2ZpbHRlcihwcm9maWxlICVpbiUgYygic3RuXzA0MyIsICJwMTZuXzEwMCIpKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCwgeCA9IHByYWNtYTo6bnRocm9vdChERi9EWiwgNSksIGdyb3VwID0gZmFjdG9yKHRpbWUpKSkgICsgZ2VvbV9wb2ludChzaXplID0gMywgc3Ryb2tlID0gMSkrCiAgZ2VvbV9wYXRoKCkgKwogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMSwgLjEpLCBicmVha3MgPSBzZXEoZnJvbSA9IC0yLCB0byA9IC43NSwgYnkgPSAwLjUpKSArCiAgI3NjYWxlX3hfbG9nMTAoKSArCiAgIHNjYWxlX2NvbG9yX2dyYWRpZW50Mihsb3cgPSAiZGFya2dyZWVuIiwgbWlkID0gImdyYXk4MCIsIGhpZ2ggPSAicHVycGxlIiwgbWlkcG9pbnQgPSAxMCkgKyBzY2FsZV9zaGFwZV9tYW51YWwobmFtZSA9ICJEYXkgb2YgTW9udGgiLCB2YWx1ZXMgPSByZXAoMjE6MjUsIDIpKSArIAogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKG5hbWUgPSAiSG91ciIsIGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMjAwLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSsKICBsYWJzKHggPSBicXVvdGUoKERGL0RaKV57MS81fX4owrVtb2xDL21eMy9kKV57MS81fSksIHkgPSAiRGVwdGggKG0pIikgKyB0aGVtZShsZWdlbmQucG9zID0gIm5vbmUiKQogICNsYWJzKHggPSAiKERGL0RaKSBeIDEvNSAowrVtb2wgQy9tXjMvZCkgXiAxLzUiKQoKcGx0RGVsdGEzUDE2CiNwbG90bHk6OmdncGxvdGx5KHBsdDFwb3MpCmBgYAoKYGBge3IgZmlnLndpZHRoID0gNiwgZmlnLmhlaWdodCA9IDR9Cm9zbXNfcDE2IDwtIGJkcyAlPiUgZmlsdGVyKHByb2plY3QgPT0gIlAxNiIpICU+JQogIGdncGxvdChhZXMoeSA9IGRlcHRoLCB4ID0gcHJhY21hOjpudGhyb290KG9zcHNEWiwgMyksIGdyb3VwID0gZmFjdG9yKHRpbWUpKSkgKyBnZW9tX3BvaW50KHNpemUgPSAzKSArIGdlb21fcGF0aCgpICsgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMSwgMSkpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKSArICAgc2NhbGVfc2hhcGVfbWFudWFsKG5hbWUgPSAiRGF5IG9mIE1vbnRoIiwgdmFsdWVzID0gcmVwKDIxOjI1LCAyKSkgKyBsYWJzKHggPSAiT2JzZXJ2ZWQgLSBNb2RlbGVkIFNtYWxsIFBhcnRpY2xlIEZsdXggXG4gwrVtb2wvbV4zL2RheSIpICsKICBzY2FsZV9maWxsX2dyYWRpZW50bihuYW1lID0gIkhvdXIgb2YgRGF5IiwgYnJlYWtzID0gYygwLCA2LCAxMiwgMTgsIDI0KSwgY29sb3JzID0gYygiYmxhY2siLCAiYmx1ZSIsICJ3aGl0ZSIsICJvcmFuZ2UiLCAiYmxhY2siKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNzUsIGNvbG9yID0gImRhcmtncmVlbiIpIApvc21zX3AxNgojZ2dzYXZlKCIuLmZpZ3VyZXMvRmx1eFNpemVTaGlmdC5zdmciCgpgYGAKCmBgYHtyIGZpZy53aWR0aCA9IDgsIGZpZy5oZWlnaHQ9OH0KcGxvdF9ncmlkKAogIHBsdEZseFAxNiwKICBwbHREZWx0YTNQMTYsCiAgb3Ntc19wMTYKKQoKZ2dzYXZlKCJmaWd1cmVzL1AxNkZsdXhSZWxhdGUuc3ZnIikKYGBgCgoKIyMgRUs2MAoKYGBge3J9CmRhdGFCaW5uZWQgPC0gcmVhZF9jc3YoImRhdGEvYmFja3NjYXR0ZXJfdGFibGVfZ283LmNzdiIpCmBgYAoKYGBge3J9CmRhdGFCaW5uZWRfMDEgPC0gZGF0YUJpbm5lZCAlPiUKICBtdXRhdGUodGltZU1leCA9IHdpdGhfdHoodGltZV9iaW4sIHR6b25lID0gIlVTL0NlbnRyYWwiKSApCmBgYAoKYGBge3J9CnN0YXJ0RGF5IDwtIGRhdGFCaW5uZWRfMDEkdGltZU1leCAlPiUgbmEub21pdCAlPiUgbWluICU+JSBmbG9vcl9kYXRlKHVuaXQgPSAiZGF5cyIpCmVuZERheSA8LSBkYXRhQmlubmVkXzAxJHRpbWVNZXggJT4lIG5hLm9taXQgJT4lIG1heCAlPiUgY2VpbGluZ19kYXRlKHVuaXQgPSAiZGF5cyIpCnRpbWVCcmVha3MgPC0gc2VxKGZyb20gPSBzdGFydERheSwgdG8gPSBlbmREYXksIGJ5ID0gIjEyIGhvdXJzIikKdGltZUxhYmVscyA8LSBmb3JtYXQodGltZUJyZWFrcykKYGBgCgoKYGBge3J9CnBsb3QxOGsgPC0gZGF0YUJpbm5lZF8wMSAlPiUgZmlsdGVyKGZyZXF1ZW5jeSA9PSAxODAwMCkgJT4lIGdncGxvdChhZXMoeCA9IHRpbWVNZXgsIHkgPSBkZXB0aF9iaW4sIGZpbGwgPSB2YWx1ZSkpICsgZ2VvbV90aWxlKCkgKyBzY2FsZV95X3JldmVyc2UoKSArIHNjYWxlX2ZpbGxfdmlyaWRpc19jKGxpbWl0cyA9IGMoLTE2NSwgLTc1KSwgb29iID0gc2NhbGVzOjpzcXVpc2gpICsKICBzY2FsZV94X2RhdGV0aW1lKGJyZWFrcyA9IHRpbWVCcmVha3MsIGRhdGVfbGFiZWxzID0gIiVkOjolSCIpICsgbGFicyh4ID0gImRheTo6aG91ciIsIHkgPSAiZGVwdGggKG0pIiwgZmlsbCA9ICJiYWNrc2NhdHRlciAoZEIpIikgKyB0aGVtZV9idygpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUpKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE2MCwgY29sb3IgPSAiZGFya2dyZWVuIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKQpwbG90MThrCiNnZ3NhdmUoImZpZ3VyZXMvc3RhdGlvblAyX0VLNjBfMThrT25seS5zdmciKQpnZ3NhdmUoImZpZ3VyZXMvc3RhdGlvblAyX0VLNjBfMThrT25seS5wbmciKQpgYGAKCmBgYHtyfQpwbG90MThrICsgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoNTAwLCAyMDApKQpgYGAKCgpgYGB7ciBmaWcuaGVpZ2h0PTIwLCBmaWcud2lkdGggPSA4fQpkYXRhQmlubmVkXzAxICU+JSBnZ3Bsb3QoYWVzKHggPSB0aW1lTWV4LCB5ID0gZGVwdGhfYmluLCBmaWxsID0gdmFsdWUpKSArIGdlb21fdGlsZSgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYyhsaW1pdHMgPSBjKC0xNjUsIC03NSksIG9vYiA9IHNjYWxlczo6c3F1aXNoKSArCiAgc2NhbGVfeF9kYXRldGltZShicmVha3MgPSB0aW1lQnJlYWtzLCBkYXRlX2xhYmVscyA9ICIlZDo6JUgiKSArIGxhYnMoeCA9ICJkYXk6OmhvdXIiLCB5ID0gImRlcHRoIChtKSIsIGZpbGwgPSAiYmFja3NjYXR0ZXIgKGRCKSIpICsgdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41KSkgKwogIAogIAogIGZhY2V0X3dyYXAofmZyZXF1ZW5jeSwgbmNvbCA9IDEpCgojZ2dzYXZlKCJmaWd1cmVzL3N0YXRpb25QMl9FSzYwX2dvNy5zdmciLCB3aWR0aCA9IDgsIGhlaWdodCA9IDIwKQpnZ3NhdmUoImZpZ3VyZXMvc3RhdGlvblAyX0VLNjBfZ283LnBuZyIsIHdpZHRoID0gOCwgaGVpZ2h0ID0gMjApCmBgYA==